From 20413c8a84e47c719a3874aa1c6eca52adba46a5 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Mon, 20 May 2002 12:01:37 +0000 Subject: Moved the gnutls-extra files to libextra directory. --- lib/Makefile.am | 28 +- lib/auth_srp.c | 448 ------------ lib/auth_srp.h | 31 - lib/auth_srp_passwd.c | 433 ----------- lib/auth_srp_passwd.h | 22 - lib/auth_srp_sb64.c | 310 -------- lib/crypt.c | 63 -- lib/crypt.h | 4 - lib/crypt_bcrypt.c | 773 -------------------- lib/crypt_bcrypt.h | 3 - lib/crypt_srpsha1.c | 175 ----- lib/crypt_srpsha1.h | 2 - lib/ext_srp.c | 111 --- lib/ext_srp.h | 6 - lib/gnutls-extra.h | 79 -- lib/gnutls_extra.c | 138 ---- lib/gnutls_extra.h | 9 - lib/gnutls_openpgp.c | 1702 -------------------------------------------- lib/gnutls_openpgp.h | 73 -- lib/gnutls_srp.c | 568 --------------- lib/gnutls_srp.h | 18 - libextra/Makefile.am | 26 + libextra/auth_srp.c | 448 ++++++++++++ libextra/auth_srp.h | 31 + libextra/auth_srp_passwd.c | 433 +++++++++++ libextra/auth_srp_passwd.h | 22 + libextra/auth_srp_sb64.c | 310 ++++++++ libextra/crypt.c | 63 ++ libextra/crypt.h | 4 + libextra/crypt_bcrypt.c | 773 ++++++++++++++++++++ libextra/crypt_bcrypt.h | 3 + libextra/crypt_srpsha1.c | 175 +++++ libextra/crypt_srpsha1.h | 2 + libextra/ext_srp.c | 111 +++ libextra/ext_srp.h | 6 + libextra/gnutls-extra.h | 83 +++ libextra/gnutls_extra.c | 138 ++++ libextra/gnutls_extra.h | 9 + libextra/gnutls_openpgp.c | 1702 ++++++++++++++++++++++++++++++++++++++++++++ libextra/gnutls_openpgp.h | 73 ++ libextra/gnutls_srp.c | 568 +++++++++++++++ libextra/gnutls_srp.h | 18 + 42 files changed, 5006 insertions(+), 4988 deletions(-) delete mode 100644 lib/auth_srp.c delete mode 100644 lib/auth_srp.h delete mode 100644 lib/auth_srp_passwd.c delete mode 100644 lib/auth_srp_passwd.h delete mode 100644 lib/auth_srp_sb64.c delete mode 100644 lib/crypt.c delete mode 100644 lib/crypt.h delete mode 100644 lib/crypt_bcrypt.c delete mode 100644 lib/crypt_bcrypt.h delete mode 100644 lib/crypt_srpsha1.c delete mode 100644 lib/crypt_srpsha1.h delete mode 100644 lib/ext_srp.c delete mode 100644 lib/ext_srp.h delete mode 100644 lib/gnutls-extra.h delete mode 100644 lib/gnutls_extra.c delete mode 100644 lib/gnutls_extra.h delete mode 100644 lib/gnutls_openpgp.c delete mode 100644 lib/gnutls_openpgp.h delete mode 100644 lib/gnutls_srp.c delete mode 100644 lib/gnutls_srp.h create mode 100644 libextra/Makefile.am create mode 100644 libextra/auth_srp.c create mode 100644 libextra/auth_srp.h create mode 100644 libextra/auth_srp_passwd.c create mode 100644 libextra/auth_srp_passwd.h create mode 100644 libextra/auth_srp_sb64.c create mode 100644 libextra/crypt.c create mode 100644 libextra/crypt.h create mode 100644 libextra/crypt_bcrypt.c create mode 100644 libextra/crypt_bcrypt.h create mode 100644 libextra/crypt_srpsha1.c create mode 100644 libextra/crypt_srpsha1.h create mode 100644 libextra/ext_srp.c create mode 100644 libextra/ext_srp.h create mode 100644 libextra/gnutls-extra.h create mode 100644 libextra/gnutls_extra.c create mode 100644 libextra/gnutls_extra.h create mode 100644 libextra/gnutls_openpgp.c create mode 100644 libextra/gnutls_openpgp.h create mode 100644 libextra/gnutls_srp.c create mode 100644 libextra/gnutls_srp.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 0f6d5bfbcf..94a717b070 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,4 +1,5 @@ -include_HEADERS = gnutls.h gnutls-extra.h +INCLUDES = -I../libextra +include_HEADERS = gnutls.h bin_SCRIPTS = libgnutls-config m4datadir = $(datadir)/aclocal @@ -9,9 +10,9 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls.asn pkix.asn \ gnutls_handshake.h gnutls_num.h gnutls_algorithms.h gnutls_dh.h \ gnutls_kx.h gnutls_hash_int.h gnutls_cipher_int.h gnutls_db.h \ gnutls_compress_int.h gnutls_session.h gnutls_priority.h gnutls_auth.h \ - auth_anon.h gnutls_extensions.h ext_srp.h \ - gnutls_auth_int.h crypt_bcrypt.h gnutls_random.h crypt_srpsha1.h \ - x509_b64.h gnutls_srp.h auth_srp.h auth_srp_passwd.h gnutls_v2_compat.h \ + auth_anon.h gnutls_extensions.h \ + gnutls_auth_int.h crypt_bcrypt.h gnutls_random.h \ + x509_b64.h auth_srp.h gnutls_v2_compat.h \ crypt.h libgnutls-config.in libgnutls.m4 gnutls.h.in.in gnutls_errors_int.h \ x509_asn1.h x509_der.h gnutls_datum.h auth_cert.h gnutls_mpi.h \ gnutls_pk.h gnutls_record.h gnutls_cert.h \ @@ -19,9 +20,9 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls.asn pkix.asn \ gnutls_sig.h gnutls_mem.h x509_extensions.h gnutls_ui.h \ gnutls-api.tex io_debug.h ext_max_record.h gnutls_session_pack.h \ gnutls_alert.h asn1-api.tex gnutls_str.h gnutls_state.h gnutls_x509.h \ - gnutls_openpgp.h ext_cert_type.h gnutls-extra-api.tex gnutls_extra.h + ext_cert_type.h -lib_LTLIBRARIES = libgnutls.la libgnutls-extra.la +lib_LTLIBRARIES = libgnutls.la COBJECTS = gnutls_record.c gnutls_compress.c debug.c \ @@ -39,18 +40,12 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c \ gnutls_str.c gnutls_state.c gnutls_x509.c \ ext_cert_type.c -COBJECTS_EXTRA = crypt_bcrypt.c crypt.c crypt_srpsha1.c ext_srp.c \ - gnutls_srp.c auth_srp.c auth_srp_passwd.c auth_srp_sb64.c \ - gnutls_openpgp.c ext_cert_type.c gnutls_extra.c - # Separate so we can create the documentation COBJECTS2 = x509_ASN.y x509_asn1.c x509_der.c libgnutls_la_SOURCES = $(COBJECTS) $(COBJECTS2) -libgnutls_extra_la_SOURCES = $(COBJECTS_EXTRA) libgnutls_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -libgnutls_extra_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) pkix_asn1_tab.c: pkix.asn -../src/asn1c pkix.asn pkix_asn1_tab.c @@ -65,13 +60,6 @@ gnutls-api.tex: $(COBJECTS) && echo "ok"; \ done -gnutls-extra-api.tex: $(COBJECTS_EXTRA) - @echo "" > gnutls-extra-api.tex - @for i in $(COBJECTS_EXTRA); \ - do echo -n "Creating documentation for file $$i... " && ../doc/scripts/gdoc -tex $$i >> gnutls-extra-api.tex \ - && echo "ok"; \ - done - asn1-api.tex: $(COBJECTS2) @echo "" > asn1-api.tex @for i in $(COBJECTS2); \ @@ -79,4 +67,4 @@ asn1-api.tex: $(COBJECTS2) && echo "ok"; \ done -all-local: gnutls-api.tex gnutls-extra-api.tex asn1-api.tex +all-local: gnutls-api.tex asn1-api.tex diff --git a/lib/auth_srp.c b/lib/auth_srp.c deleted file mode 100644 index 45f0295335..0000000000 --- a/lib/auth_srp.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (C) 2001 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * GNUTLS 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 2 of the License, or - * (at your option) any later version. - * - * GNUTLS 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "gnutls_int.h" - -#ifdef ENABLE_SRP - -#include "gnutls_errors.h" -#include "auth_srp_passwd.h" -#include "gnutls_auth.h" -#include "gnutls_auth_int.h" -#include "gnutls_srp.h" -#include "debug.h" -#include "gnutls_num.h" -#include "auth_srp.h" -#include - -int gen_srp_server_kx2(GNUTLS_STATE, opaque **); -int gen_srp_client_kx0(GNUTLS_STATE, opaque **); - -int proc_srp_server_kx2(GNUTLS_STATE, opaque *, int); -int proc_srp_client_kx0(GNUTLS_STATE, opaque *, int); - -const MOD_AUTH_STRUCT srp_auth_struct = { - "SRP", - NULL, - NULL, - NULL, - gen_srp_server_kx2, - gen_srp_client_kx0, - NULL, - NULL, - NULL, - - NULL, - NULL, /* certificate */ - NULL, - proc_srp_server_kx2, - proc_srp_client_kx0, - NULL, - NULL, - NULL -}; - - -#define _b state->gnutls_key->b -#define B state->gnutls_key->B -#define _a state->gnutls_key->a -#define A state->gnutls_key->A -#define N state->gnutls_key->client_p -#define G state->gnutls_key->client_g -#define V state->gnutls_key->x -#define S state->gnutls_key->KEY - -/* Send the first key exchange message ( g, n, s) and append the verifier algorithm number - * Data is allocated by the caller, and should have data_size size. - */ -int gen_srp_server_hello(GNUTLS_STATE state, opaque * data, int data_size) -{ - size_t n_g, n_n, n_s; - size_t ret; - uint8 *data_n, *data_s; - uint8 *data_g, *username; - uint8 pwd_algo; - GNUTLS_SRP_PWD_ENTRY *pwd_entry; - int err; - SRP_SERVER_AUTH_INFO info; - - if ( (ret=_gnutls_auth_info_set( state, GNUTLS_CRD_SRP, sizeof( SRP_SERVER_AUTH_INFO_INT), 1)) < 0) { - gnutls_assert(); - return ret; - } - - info = _gnutls_get_auth_info( state); - username = info->username; - - _gnutls_str_cpy( username, MAX_SRP_USERNAME, state->security_parameters.extensions.srp_username); - - pwd_entry = _gnutls_srp_pwd_read_entry( state, username, &err); - - if (pwd_entry == NULL) { - if (err==0) - /* in order to avoid informing the peer that - * username does not exist. - */ - pwd_entry = _gnutls_randomize_pwd_entry(); - else - return GNUTLS_E_PWD_ERROR; - } - - pwd_algo = (uint8) pwd_entry->algorithm; - - if (_gnutls_mpi_print( NULL, &n_g, pwd_entry->g)!=0) { - gnutls_assert(); - return GNUTLS_E_MPI_PRINT_FAILED; - } - if (_gnutls_mpi_print( NULL, &n_n, pwd_entry->n)!=0) { - gnutls_assert(); - return GNUTLS_E_MPI_PRINT_FAILED; - } - - /* copy from pwd_entry to local variables (actually in state) */ - G = _gnutls_mpi_alloc_like(pwd_entry->g); - N = _gnutls_mpi_alloc_like(pwd_entry->n); - V = _gnutls_mpi_alloc_like(pwd_entry->v); - - if (G==NULL || N == NULL || V == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - _gnutls_mpi_set(G, pwd_entry->g); - _gnutls_mpi_set(N, pwd_entry->n); - _gnutls_mpi_set(V, pwd_entry->v); - - if (data_size < n_n + n_g + pwd_entry->salt_size + 6 + 1) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - data_g = data; - - /* firstly copy the algorithm used to generate the verifier - */ - data_g[0] = pwd_algo; - - /* copy G (generator) to data */ - - data_g++; - - if(_gnutls_mpi_print( &data_g[2], &n_g, G)!=0) { - gnutls_assert(); - return GNUTLS_E_MPI_PRINT_FAILED; - } - - WRITEuint16( n_g, data_g); - - /* copy N (mod n) */ - data_n = &data_g[2 + n_g]; - - if (_gnutls_mpi_print( &data_n[2], &n_n, N)!=0) { - gnutls_assert(); - return GNUTLS_E_MPI_PRINT_FAILED; - } - - WRITEuint16( n_n, data_n); - - /* copy the salt */ - data_s = &data_n[2 + n_n]; - n_s = pwd_entry->salt_size; - memcpy(&data_s[2], pwd_entry->salt, n_s); - - WRITEuint16( n_s, data_s); - - ret = n_g + n_n + pwd_entry->salt_size + 6 + 1; - _gnutls_srp_clear_pwd_entry( pwd_entry); - - return ret; -} - -/* send the second key exchange message */ -int gen_srp_server_kx2(GNUTLS_STATE state, opaque ** data) -{ - int ret; - size_t n_b; - uint8 *data_b; - - /* calculate: B = (v + g^b) % N */ - B = _gnutls_calc_srp_B( &_b, G, N, V); - if (B==NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - if (_gnutls_mpi_print( NULL, &n_b, B)!=0) - return GNUTLS_E_MPI_PRINT_FAILED; - - (*data) = gnutls_malloc(n_b + 2); - if ( (*data) == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - /* copy B */ - data_b = (*data); - if (_gnutls_mpi_print( &data_b[2], &n_b, B)!=0) - return GNUTLS_E_MPI_PRINT_FAILED; - - WRITEuint16( n_b, data_b); - - /* calculate u */ - state->gnutls_key->u = _gnutls_calc_srp_u(B); - if (state->gnutls_key->u==NULL) { - gnutls_assert(); - gnutls_free( *data); - return GNUTLS_E_MEMORY_ERROR; - } - - /* S = (A * v^u) ^ b % N */ - S = _gnutls_calc_srp_S1( A, _b, state->gnutls_key->u, V, N); - if ( S==NULL) { - gnutls_assert(); - gnutls_free( *data); - return GNUTLS_E_MEMORY_ERROR; - } - - _gnutls_mpi_release(&A); - _gnutls_mpi_release(&_b); - _gnutls_mpi_release(&V); - _gnutls_mpi_release(&state->gnutls_key->u); - _gnutls_mpi_release(&B); - - ret = _gnutls_generate_key( state->gnutls_key); - _gnutls_mpi_release( &S); - - if (ret < 0) - return ret; - - return n_b + 2; -} - - -/* return A = g^a % N */ -int gen_srp_client_kx0(GNUTLS_STATE state, opaque ** data) -{ - size_t n_a; - uint8 *data_a; - char *username; - char *password; - const GNUTLS_SRP_CLIENT_CREDENTIALS cred = - _gnutls_get_cred(state->gnutls_key, GNUTLS_CRD_SRP, NULL); - - if (cred == NULL) { - gnutls_assert(); - return GNUTLS_E_INSUFICIENT_CRED; - } - - username = cred->username; - password = cred->password; - - if (username == NULL || password == NULL) - return GNUTLS_E_INSUFICIENT_CRED; - - /* calc A = g^a % N */ - if (G == NULL || N == NULL) { - gnutls_assert(); - return GNUTLS_E_INSUFICIENT_CRED; - } - - A = _gnutls_calc_srp_A( &_a, G, N); - if (A==NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - if (_gnutls_mpi_print( NULL, &n_a, A)!=0) - return GNUTLS_E_MPI_PRINT_FAILED; - - (*data) = gnutls_malloc(n_a + 2); - if ( (*data) == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - /* copy A */ - data_a = (*data); - if (_gnutls_mpi_print( &data_a[2], &n_a, A)!=0) { - gnutls_free( *data); - return GNUTLS_E_MPI_PRINT_FAILED; - } - - WRITEuint16( n_a, data_a); - - return n_a + 2; -} - -/* receive the first key exchange message ( g, n, s) */ -int proc_srp_server_hello(GNUTLS_STATE state, const opaque * data, int data_size) -{ - uint16 n_s, n_g, n_n; - size_t _n_s, _n_g, _n_n; - const uint8 *data_n; - const uint8 *data_g; - const uint8 *data_s; - uint8 pwd_algo; - int i, ret; - opaque hd[SRP_MAX_HASH_SIZE]; - char *username; - char *password; - const GNUTLS_SRP_CLIENT_CREDENTIALS cred = - _gnutls_get_cred(state->gnutls_key, GNUTLS_CRD_SRP, NULL); - - if (cred == NULL) { - gnutls_assert(); - return GNUTLS_E_INSUFICIENT_CRED; - } - - username = cred->username; - password = cred->password; - - if (username == NULL || password == NULL) - return GNUTLS_E_INSUFICIENT_CRED; - -/* read the algorithm used to generate V */ - - i = 0; - DECR_LEN( data_size, 1); - pwd_algo = data[0]; - i++; - - DECR_LEN( data_size, 2); - n_g = READuint16( &data[i]); - i += 2; - - DECR_LEN( data_size, n_g); - data_g = &data[i]; - i += n_g; - if (i > data_size) { - gnutls_assert(); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - - DECR_LEN( data_size, 2); - n_n = READuint16( &data[i]); - i += 2; - - DECR_LEN( data_size, n_n); - data_n = &data[i]; - i += n_n; - - DECR_LEN( data_size, 2); - n_s = READuint16( &data[i]); - i += 2; - - DECR_LEN( data_size, n_s); - data_s = &data[i]; - i += n_s; - - _n_s = n_s; - _n_g = n_g; - _n_n = n_n; - - if (_gnutls_mpi_scan(&N, data_n, &_n_n) != 0 || N == NULL) { - gnutls_assert(); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - if (_gnutls_mpi_scan(&G, data_g, &_n_g) != 0 || G == NULL) { - gnutls_assert(); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - /* generate x = SHA(s | SHA(U | ":" | p)) - * (or the equivalent using bcrypt) - */ - if ( ( ret =_gnutls_calc_srp_x( username, password, (opaque*)data_s, n_s, pwd_algo, &_n_g, hd)) < 0) { - gnutls_assert(); - return ret; - } - - if (_gnutls_mpi_scan(&state->gnutls_key->x, hd, &_n_g) != 0 || state->gnutls_key->x==NULL) { - gnutls_assert(); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - return 0; -} - -/* just read A and put it to state */ -int proc_srp_client_kx0(GNUTLS_STATE state, opaque * data, int data_size) -{ - size_t _n_A; - - DECR_LEN( data_size, 2); - _n_A = READuint16( &data[0]); - - DECR_LEN( data_size, _n_A); - if (_gnutls_mpi_scan(&A, &data[2], &_n_A) || A == NULL) { - gnutls_assert(); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - return 0; -} - - -int proc_srp_server_kx2(GNUTLS_STATE state, opaque * data, int data_size) -{ - size_t _n_B; - int ret; - - DECR_LEN( data_size, 2); - _n_B = READuint16( &data[0]); - - DECR_LEN( data_size, _n_B); - if (_gnutls_mpi_scan(&B, &data[2], &_n_B) || B==NULL) { - gnutls_assert(); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - /* calculate u */ - state->gnutls_key->u = _gnutls_calc_srp_u( B); - if ( state->gnutls_key->u == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - /* S = (B - g^x) ^ (a + u * x) % N */ - S = _gnutls_calc_srp_S2( B, G, state->gnutls_key->x, _a, state->gnutls_key->u, N); - if (S==NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - - _gnutls_mpi_release(&A); - _gnutls_mpi_release(&_b); - _gnutls_mpi_release(&V); - _gnutls_mpi_release(&state->gnutls_key->u); - _gnutls_mpi_release(&B); - - ret = _gnutls_generate_key( state->gnutls_key); - _gnutls_mpi_release(&S); - - if (ret < 0) - return ret; - - return 0; -} - -#endif /* ENABLE_SRP */ diff --git a/lib/auth_srp.h b/lib/auth_srp.h deleted file mode 100644 index a01475b9a6..0000000000 --- a/lib/auth_srp.h +++ /dev/null @@ -1,31 +0,0 @@ -#include - - -typedef struct { - char* username; - char* password; -} SRP_CLIENT_CREDENTIALS_INT; - -#define GNUTLS_SRP_CLIENT_CREDENTIALS SRP_CLIENT_CREDENTIALS_INT* - -typedef struct { - char** password_file; - char** password_conf_file; - int password_files; -} SRP_SERVER_CREDENTIALS_INT; - -#define GNUTLS_SRP_SERVER_CREDENTIALS SRP_SERVER_CREDENTIALS_INT* - -/* these structures should not use allocated data */ -typedef struct SRP_SERVER_AUTH_INFO_INT { - char username[MAX_SRP_USERNAME]; -} *SRP_SERVER_AUTH_INFO; - -#ifdef ENABLE_SRP - -int proc_srp_server_hello(GNUTLS_STATE state, const opaque * data, int data_size); -int gen_srp_server_hello(GNUTLS_STATE state, opaque * data, int data_size); - -typedef struct SRP_SERVER_AUTH_INFO_INT SRP_SERVER_AUTH_INFO_INT; - -#endif /* ENABLE_SRP */ diff --git a/lib/auth_srp_passwd.c b/lib/auth_srp_passwd.c deleted file mode 100644 index d47df6ec7a..0000000000 --- a/lib/auth_srp_passwd.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (C) 2001 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * GNUTLS 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 2 of the License, or - * (at your option) any later version. - * - * GNUTLS 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* Functions for operating in an SRP passwd file are included here */ - -#include "gnutls_int.h" - -#ifdef ENABLE_SRP - -#include "x509_b64.h" -#include "gnutls_errors.h" -#include "auth_srp_passwd.h" -#include "auth_srp.h" -#include "gnutls_auth_int.h" -#include "gnutls_srp.h" -#include "gnutls_random.h" -#include "gnutls_dh.h" -#include "debug.h" -#include - -/* this function parses tpasswd.conf file. Format is: - * string(username):base64(v):base64(salt):int(index) - */ -static int pwd_put_values( GNUTLS_SRP_PWD_ENTRY *entry, char *str, int str_size) { -char * p, *p2; -int len; -opaque *verifier; -int verifier_size; -int indx; - - p = rindex( str, ':'); /* we have index */ - if (p==NULL) { - gnutls_assert(); - return GNUTLS_E_PARSING_ERROR; - } - - *p='\0'; - p++; - - len = strlen(p); - indx = atoi(p); - if (indx==0) { - gnutls_assert(); - return GNUTLS_E_PARSING_ERROR; - } - - /* now go for salt */ - p = rindex( str, ':'); /* we have salt */ - if (p==NULL) { - gnutls_assert(); - return GNUTLS_E_PARSING_ERROR; - } - - *p='\0'; - p++; - - len = strlen(p); - - entry->salt_size = _gnutls_sbase64_decode( p, len, &entry->salt); - - if (entry->salt_size <= 0) { - gnutls_assert(); - return GNUTLS_E_PARSING_ERROR; - } - - /* now go for verifier */ - p = rindex( str, ':'); /* we have verifier */ - if (p==NULL) { - gnutls_free(entry->salt); - return GNUTLS_E_PARSING_ERROR; - } - - *p='\0'; - p++; - - if ( (p2 = index(p, '$')) == NULL) { - entry->algorithm = SRPSHA1_CRYPT; - } else { - p++; - entry->algorithm = atoi(p); - p2 = index(p, '$'); /* find the last $ */ - if (p2==NULL) { - gnutls_assert(); - gnutls_free(entry->salt); - return GNUTLS_E_PARSING_ERROR; - } - p = p2+1; - } - - len = strlen(p); - verifier_size = _gnutls_sbase64_decode( p, len, &verifier); - if (verifier_size <= 0) { - gnutls_assert(); - gnutls_free(entry->salt); - return GNUTLS_E_PARSING_ERROR; - } - - if (_gnutls_mpi_scan(&entry->v, verifier, &verifier_size) || entry->v == NULL) { - gnutls_assert(); - gnutls_free( entry->salt); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - gnutls_free( verifier); - - /* now go for username */ - *p='\0'; - - entry->username = gnutls_strdup(str); - if (entry->username==NULL) { - gnutls_free( entry->salt); - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - return indx; -} - - -/* this function parses tpasswd.conf file. Format is: - * int(index):base64(n):int(g) - */ -static int pwd_put_values2( GNUTLS_SRP_PWD_ENTRY *entry, char *str, int str_size) { -char * p; -int len; -opaque * tmp; -int tmp_size; - - p = rindex( str, ':'); /* we have g */ - if (p==NULL) { - gnutls_assert(); - return GNUTLS_E_PARSING_ERROR; - } - - *p='\0'; - p++; - - /* read the generator */ - len = strlen(p); - if (p[len-1]=='\n' || p[len-1]==' ') len--; - tmp_size = _gnutls_sbase64_decode( p, len, &tmp); - - if (tmp_size < 0) { - gnutls_assert(); - return GNUTLS_E_PARSING_ERROR; - } - if (_gnutls_mpi_scan(&entry->g, tmp, &tmp_size) || entry->g==NULL) { - gnutls_assert(); - gnutls_free(tmp); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - gnutls_free(tmp); - - - /* now go for n - modulo */ - p = rindex( str, ':'); /* we have n */ - if (p==NULL) { - _gnutls_mpi_release(&entry->g); - gnutls_assert(); - return GNUTLS_E_PARSING_ERROR; - } - - *p='\0'; - p++; - - len = strlen(p); - tmp_size = _gnutls_sbase64_decode( p, len, &tmp); - - if (tmp_size < 0) { - gnutls_assert(); - _gnutls_mpi_release(&entry->g); - return GNUTLS_E_PARSING_ERROR; - } - if (_gnutls_mpi_scan(&entry->n, tmp, &tmp_size) || entry->n==NULL) { - gnutls_assert(); - gnutls_free(tmp); - _gnutls_mpi_release(&entry->g); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - gnutls_free(tmp); - - return 0; -} - - -/* this function opens the tpasswd.conf file - */ -static int pwd_read_conf( const char* pconf_file, GNUTLS_SRP_PWD_ENTRY* entry, int index) { - FILE * fd; - char line[2*1024]; - int i; - char indexstr[10]; - - sprintf( indexstr, "%d", index); /* Flawfinder: ignore */ - - fd = fopen( pconf_file, "r"); - if (fd==NULL) { - gnutls_assert(); - return GNUTLS_E_FILE_ERROR; - } - - while( fgets( line, sizeof(line), fd) != NULL) { - /* move to first ':' */ - i=0; - while( (line[i]!=':') && (line[i]!='\0') && (i < sizeof(line)) ) { - i++; - } - if (strncmp( indexstr, line, strlen(indexstr)) == 0) { - if ((index = pwd_put_values2( entry, line, strlen(line))) >= 0) - return 0; - else { - return GNUTLS_E_PWD_ERROR; - } - } - } - return GNUTLS_E_PWD_ERROR; - -} - - -GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_STATE state, char* username, int *err) { - const GNUTLS_SRP_SERVER_CREDENTIALS cred; - FILE * fd; - char line[2*1024]; - int i, len; - GNUTLS_SRP_PWD_ENTRY * entry = gnutls_malloc(sizeof(GNUTLS_SRP_PWD_ENTRY)); - int index; - int pwd_index = 0; - - if (entry==NULL) { - gnutls_assert(); - *err = 1; - return NULL; - } - - *err = 0; /* normal exit */ - - cred = _gnutls_get_cred( state->gnutls_key, GNUTLS_CRD_SRP, NULL); - if (cred==NULL) { - *err = 1; - gnutls_assert(); - gnutls_free(entry); - return NULL; - } - - if (cred->password_files<=0) { - gnutls_assert(); - return NULL; - } - - /* use the callback to select a password file */ - if (state->gnutls_internals.server_srp_callback!=NULL) { - pwd_index = state->gnutls_internals.server_srp_callback( - state, cred->password_file, cred->password_conf_file, - cred->password_files); - - if (pwd_index < 0) { - gnutls_assert(); - return NULL; - } - } - - fd = fopen( cred->password_file[pwd_index], "r"); - if (fd==NULL) { - *err = 1; /* failed due to critical error */ - gnutls_assert(); - gnutls_free(entry); - return NULL; - } - - while( fgets( line, sizeof(line), fd) != NULL) { - /* move to first ':' */ - i=0; - while( (line[i]!=':') && (line[i]!='\0') && (i < sizeof(line)) ) { - i++; - } - len = strlen(username); - if (strncmp( username, line, (i>len)?i:len) == 0) { - if ((index = pwd_put_values( entry, line, strlen(line))) >= 0) - if (pwd_read_conf( cred->password_conf_file[pwd_index], entry, index)==0) { - return entry; - } else { - gnutls_free(entry); - return NULL; - } - else { - gnutls_free(entry); - return NULL; - } - } - } - return NULL; - -} -#define RNDUSER "rnd" -#define RND_SALT_SIZE 17 -GNUTLS_SRP_PWD_ENTRY* _gnutls_randomize_pwd_entry() { - GNUTLS_SRP_PWD_ENTRY * pwd_entry = gnutls_calloc(1, sizeof(GNUTLS_SRP_PWD_ENTRY)); - - if (pwd_entry == NULL) { - gnutls_assert(); - return NULL; - } - - pwd_entry->g = _gnutls_get_rnd_srp_params( &pwd_entry->n, 1024); - if (pwd_entry->g==NULL || pwd_entry->n==NULL) { - gnutls_assert(); - _gnutls_srp_clear_pwd_entry( pwd_entry); - return NULL; - } - - pwd_entry->username = gnutls_malloc(strlen(RNDUSER)+1); - if (pwd_entry->username == NULL) { - gnutls_assert(); - _gnutls_srp_clear_pwd_entry( pwd_entry); - return NULL; - } - _gnutls_str_cpy( pwd_entry->username, MAX_SRP_USERNAME, RNDUSER); /* Flawfinder: ignore */ - - pwd_entry->v = _gnutls_mpi_new(160); - if (pwd_entry->v==NULL) { - gnutls_assert(); - _gnutls_srp_clear_pwd_entry( pwd_entry); - return NULL; - } - - _gnutls_mpi_randomize( pwd_entry->v, 160, GCRY_WEAK_RANDOM); - - pwd_entry->salt_size = RND_SALT_SIZE; - - pwd_entry->salt = gnutls_malloc(RND_SALT_SIZE); - if (pwd_entry->salt==NULL) { - gnutls_assert(); - _gnutls_srp_clear_pwd_entry( pwd_entry); - return NULL; - } - - if (_gnutls_get_random(pwd_entry->salt, RND_SALT_SIZE, GNUTLS_WEAK_RANDOM) < 0) { - gnutls_assert(); - _gnutls_srp_clear_pwd_entry( pwd_entry); - return NULL; - } - - pwd_entry->algorithm = 0; - - return pwd_entry; - -} - -void _gnutls_srp_clear_pwd_entry( GNUTLS_SRP_PWD_ENTRY * entry) { - _gnutls_mpi_release(&entry->v); - _gnutls_mpi_release(&entry->g); - _gnutls_mpi_release(&entry->n); - - gnutls_free(entry->salt); - gnutls_free(entry->username); - - gnutls_free(entry); - - return; -} - -/* Generates a prime and a generator, and returns the srpbase64 encoded value. - */ -int _gnutls_srp_generate_prime(opaque ** ret_g, opaque ** ret_n, int bits) -{ - - GNUTLS_MPI prime, g; - int siz; - char *tmp; - - if ( _gnutls_dh_generate_prime(&g, &prime, bits) < 0) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - siz = 0; - _gnutls_mpi_print( NULL, &siz, g); - if (ret_g != NULL) { - tmp = gnutls_malloc(siz); - if (tmp==NULL) return GNUTLS_E_MEMORY_ERROR; - - _gnutls_mpi_print( tmp, &siz, g); - - if (_gnutls_sbase64_encode(tmp, siz, ret_g) < 0) { - gnutls_free(tmp); - return GNUTLS_E_UNKNOWN_ERROR; - } - gnutls_free(tmp); - } - - siz = 0; - _gnutls_mpi_print( NULL, &siz, prime); - if (ret_n != NULL) { - tmp = gnutls_malloc(siz); - if (tmp==NULL) return GNUTLS_E_MEMORY_ERROR; - - _gnutls_mpi_print( tmp, &siz, prime); - if (_gnutls_sbase64_encode(tmp, siz, ret_n) < 0) { - gnutls_free(tmp); - return GNUTLS_E_UNKNOWN_ERROR; - } - - gnutls_free(tmp); - } - - _gnutls_mpi_release(&g); - _gnutls_mpi_release(&prime); - - return 0; - -} - -#endif /* ENABLE SRP */ diff --git a/lib/auth_srp_passwd.h b/lib/auth_srp_passwd.h deleted file mode 100644 index 6207265542..0000000000 --- a/lib/auth_srp_passwd.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifdef ENABLE_SRP - -typedef struct { - char* username; - int algorithm; - - opaque *salt; - int salt_size; - - MPI v; - MPI g; - MPI n; -} GNUTLS_SRP_PWD_ENTRY; - -/* this is localy alocated. It should be freed using the provided function */ -GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_STATE state, char* username, int* err); -void _gnutls_srp_clear_pwd_entry( GNUTLS_SRP_PWD_ENTRY * entry); -GNUTLS_SRP_PWD_ENTRY* _gnutls_randomize_pwd_entry(void); -int _gnutls_sbase64_encode(uint8 * data, int data_size, uint8 ** result); -int _gnutls_sbase64_decode(uint8 * data, int data_size, uint8 ** result); - -#endif /* ENABLE_SRP */ diff --git a/lib/auth_srp_sb64.c b/lib/auth_srp_sb64.c deleted file mode 100644 index 3876ed5a6a..0000000000 --- a/lib/auth_srp_sb64.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (C) 2001 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * GNUTLS 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 2 of the License, or - * (at your option) any later version. - * - * GNUTLS 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "gnutls_int.h" - -#ifdef ENABLE_SRP - -/* this a modified base64 for srp !!! - * It seems that everybody makes it's own base64 convertion. - */ -const static uint8 b64table[64] = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./"; - -const static uint8 asciitable[128] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x3e, 0x3f, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, - 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, - 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, - 0x23, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x24, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, - 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, - 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, - 0xff, 0xff -}; - -inline static int encode(uint8 * result, const uint8 * rdata, int left) -{ - - int data_len; - int c, ret = 4; - uint8 data[3]; - - if (left > 3) - data_len = 3; - else - data_len = left; - - data[0] = data[1] = data[2] = 0; - memcpy(data, rdata, data_len); - - switch (data_len) { - case 3: - result[0] = b64table[((data[0] & 0xfc) >> 2)]; - result[1] = - b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff) | - ((data[1] & 0xf0) >> 4))]; - result[2] = - b64table[((((data[1] & 0x0f) << 2) & 0xff) | - ((data[2] & 0xc0) >> 6))]; - result[3] = b64table[(data[2] & 0x3f) & 0xff]; - break; - case 2: - if ((c = ((data[0] & 0xf0) >> 4)) != 0) { - result[0] = b64table[c]; - result[1] = - b64table[((((data[0] & 0x0f) << 2) & 0xff) | - ((data[1] & 0xc0) >> 6))]; - result[2] = b64table[(data[1] & 0x3f) & 0xff]; - result[3] = '\0'; - ret -= 1; - } else { - if ((c = - ((data[0] & 0x0f) << 2) | ((data[1] & 0xc0) >> - 6)) != 0) { - result[0] = b64table[c]; - result[1] = b64table[data[1] & 0x3f]; - result[2] = '\0'; - result[3] = '\0'; - ret -= 2; - } else { - result[0] = b64table[data[0] & 0x3f]; - result[1] = '\0'; - result[2] = '\0'; - result[3] = '\0'; - ret -= 3; - } - } - break; - case 1: - if ((c = ((data[0] & 0xc0) >> 6)) != 0) { - result[0] = b64table[c]; - result[1] = b64table[(data[0] & 0x3f) & 0xff]; - result[2] = '\0'; - result[3] = '\0'; - ret -= 2; - } else { - result[0] = b64table[(data[0] & 0x3f) & 0xff]; - result[1] = '\0'; - result[2] = '\0'; - result[3] = '\0'; - ret -= 3; - } - break; - default: - return -1; - } - - return ret; - -} - -/* encodes data and puts the result into result (localy alocated) - * The result_size is the return value - */ -int _gnutls_sbase64_encode(uint8 * data, int data_size, uint8 ** result) -{ - int ret, tmp, j, i; - char tmpres[4]; - int mod = data_size % 3; - - ret = mod; - if (ret != 0) - ret = 4; - else - ret = 0; - - ret += (data_size * 4) / 3; - - (*result) = gnutls_calloc( 1, ret + 1); - if ((*result) == NULL) - return -1; - - i = j = 0; -/* encode the bytes that are not a multiple of 3 - */ - if (mod > 0) { - tmp = encode(tmpres, &data[0], mod); - if (tmp < 0) { - gnutls_free( (*result)); - return tmp; - } - - memcpy(&(*result)[0], tmpres, tmp); - i = mod; - j = tmp; - - } -/* encode the rest - */ - for (; i < data_size; i += 3, j += 4) { - tmp = encode(tmpres, &data[i], data_size - i); - if (tmp < 0) { - gnutls_free( (*result)); - return tmp; - } - memcpy(&(*result)[j], tmpres, tmp); - } - - return strlen(*result); -} - - -/* data must be 4 bytes - * result should be 3 bytes - */ -#define TOASCII(c) (c < 127 ? asciitable[c] : 0xff) -inline static int decode(uint8 * result, const uint8 * data) -{ - uint8 a1, a2; - int ret = 3; - - memset( result, 0, 3); - - a1 = TOASCII(data[3]); - a2 = TOASCII(data[2]); - if (a1 != 0xff) result[2] = a1 & 0xff; - else return -1; - if (a2 != 0xff) result[2] |= ((a2 & 0x03) << 6) & 0xff; - - a1 = a2; - a2 = TOASCII(data[1]); - if (a1 != 0xff) result[1] = ((a1 & 0x3c) >> 2); - if (a2 != 0xff) result[1] |= ((a2 & 0x0f) << 4); - else if (a1==0xff || result[1] == 0) ret--; - - a1 = a2; - a2 = TOASCII(data[0]); - if (a1 != 0xff) result[0] = (((a1 & 0x30) >> 4) & 0xff); - if (a2 != 0xff) result[0] |= ((a2 << 2) & 0xff); - else if (a1==0xff || result[0] == 0) ret--; - - return ret; -} - -/* decodes data and puts the result into result (localy alocated) - * The result_size is the return value. - * That function does not ignore newlines tabs etc. You should remove them - * before calling it. - */ -int _gnutls_sbase64_decode(uint8 * data, int idata_size, uint8 ** result) -{ - int i, ret, j, left; - int data_size, tmp; - uint8 datrev[4]; - uint8 tmpres[3]; - - data_size = (idata_size/4)*4; - left = idata_size % 4; - - ret = (data_size / 4) * 3; - - if (left > 0) - ret += 3; - - (*result) = gnutls_malloc(ret+1); - if ((*result) == NULL) - return -1; - - /* the first "block" is treated with special care */ - tmp = 0; - if (left > 0) { - memset( datrev, 0, 4); - memcpy( &datrev[4-left], data, left); - - tmp = decode( tmpres, datrev); - if (tmp < 0) { - gnutls_free( (*result)); - return tmp; - } - - memcpy( *result, &tmpres[3-tmp], tmp); - if (tmp < 3) - ret -= (3 - tmp); - } - - /* rest data */ - for (i = left, j = tmp; i < idata_size; i += 4) { - tmp = decode(tmpres, &data[i]); - if (tmp < 0) { - gnutls_free( (*result)); - return tmp; - } - memcpy(&(*result)[j], tmpres, tmp); - if (tmp < 3) - ret -= (3 - tmp); - j += 3; - } - - return ret; -} - -#ifdef B64_TEST -int main() -{ - char x[100 * 1024]; - int siz; - uint8 *b64; - -/* for (i = 0; i < 128; i++) { - if (i % 6 == 0) - fprintf(stdout, "\n"); - if (strchr(b64table, i) == NULL) - fprintf(stdout, "0x%.2x, ", 0xff); - else - fprintf(stdout, "0x%.2x, ", - (int) ((int) index(b64table, i) - - (int) b64table)); - - - } - return 0;*/ - siz = fread(x, 1, sizeof(x), stdin); - -// siz = _gnutls_sbase64_encode(x, siz, &b64); - siz = _gnutls_sbase64_decode(x, siz, &b64); - - - if (siz < 0) { - _gnutls_log( "ERROR %d\n", siz); - exit(1); - } - - fwrite(b64, siz, 1, stdout); - return 0; - - -} -#endif - -#endif /* ENABLE_SRP */ diff --git a/lib/crypt.c b/lib/crypt.c deleted file mode 100644 index 6da9c339b5..0000000000 --- a/lib/crypt.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2000,2001 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * GNUTLS 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 2 of the License, or - * (at your option) any later version. - * - * GNUTLS 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "gnutls_int.h" - -#ifdef ENABLE_SRP - -#include "crypt_bcrypt.h" -#include "crypt_srpsha1.h" -#include "gnutls_random.h" - -char * gnutls_crypt(const char* username, const char *passwd, crypt_algo algo, int salt, GNUTLS_MPI g, GNUTLS_MPI n) { - - switch(algo) { - case BLOWFISH_CRYPT: /* bcrypt */ - /* salt in bcrypt is actually the cost */ - return crypt_bcrypt_wrapper(username, passwd, salt, g, n); - case SRPSHA1_CRYPT: /* bcrypt */ - /* salt in bcrypt is the salt size */ - return crypt_srpsha1_wrapper(username, passwd, salt, g, n); - } - return NULL; -} - -int gnutls_crypt_vrfy(const char* username, const char *passwd, char* salt, GNUTLS_MPI g, GNUTLS_MPI n) { - char* cr; - - switch(salt[0]) { - case '$': - switch(salt[1]) { - case '2': - cr = crypt_bcrypt(username, passwd, salt, g, n); - if (cr==NULL) return 1; - if (strncmp(cr, salt, strlen(cr))==0) return 0; - break; - } - default: - cr = crypt_srpsha1(username, passwd, salt, g, n); - if (cr==NULL) return 1; - if (strncmp(cr, salt, strlen(cr))==0) return 0; - break; - } - return 1; -} - -#endif diff --git a/lib/crypt.h b/lib/crypt.h deleted file mode 100644 index 205ec72136..0000000000 --- a/lib/crypt.h +++ /dev/null @@ -1,4 +0,0 @@ -/* crypt functions */ - -char * gnutls_crypt(const char* username, const char *passwd, crypt_algo algo, int salt, MPI g, MPI n); -int gnutls_crypt_vrfy(const char* username, const char *passwd, char* salt, MPI g, MPI n); diff --git a/lib/crypt_bcrypt.c b/lib/crypt_bcrypt.c deleted file mode 100644 index 55ece44c4b..0000000000 --- a/lib/crypt_bcrypt.c +++ /dev/null @@ -1,773 +0,0 @@ -/* - * Copyright (C) 2000,2001 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * GNUTLS 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 2 of the License, or - * (at your option) any later version. - * - * GNUTLS 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* - * This is a modified version of the blowfish algorithm. - * It is an implementation of the bcrypt algorithm as described - * in a usenix paper by Niels Provos and David Mazieres. - * This is the encoding algorithm used in OpenBSD for passwords. - * (includes a modified version of b64.c) - */ - -/* The differences here from the original openbsd bcrypt algorithm are: - * 1. we use a different b64 hash function - * (the one used in SRP password files), - * 2. we use all the bytes from the encryption step (openbsd omited one byte), - * 3. we use the first 24 bytes of CONCAT(username,NULL,"Orphean...") as the - * encryption string. - */ - -#include "gnutls_int.h" - -#ifdef ENABLE_SRP - -#include "crypt_bcrypt.h" -#include "gnutls_random.h" -#include "auth_srp_passwd.h" -#include "gnutls_srp.h" -#include "gnutls_errors.h" -#include "debug.h" - -typedef struct { - uint32 S[4][256], P[18]; -} blf_ctx; - -#define BF_N 16 - -#define F(bc, x) ( ((bc->S[0][(x >> 24) & 0xff] + bc->S[1][(x >> 16) & 0xff]) ^ bc->S[2][(x >> 8) & 0xff]) + bc->S[3][x & 0xff] ) - -/* x should be a 64 bit integer */ -static void _blf_encrypt(blf_ctx * c, uint8 * x) -{ - uint32 Xl; - uint32 Xr, temp; - short i; - - Xl = x[0] << 24 | x[1] << 16 | x[2] << 8 | x[3]; - Xr = x[4] << 24 | x[5] << 16 | x[6] << 8 | x[7]; - - for (i = 0; i < BF_N; ++i) { - Xl ^= c->P[i]; - Xr ^= F(c, Xl); - - temp = Xl; - Xl = Xr; - Xr = temp; - } - - temp = Xl; - Xl = Xr; - Xr = temp; - - Xr ^= c->P[BF_N]; - Xl ^= c->P[BF_N + 1]; - - x[0] = (Xl >> 24) & 0xff; - x[1] = (Xl >> 16) & 0xff; - x[2] = (Xl >> 8) & 0xff; - x[3] = (Xl) & 0xff; - x[4] = (Xr >> 24) & 0xff; - x[5] = (Xr >> 16) & 0xff; - x[6] = (Xr >> 8) & 0xff; - x[7] = (Xr) & 0xff; -} - -/* x should be a 64 bit integer */ -static void enblf_noswap(blf_ctx * c, uint32 * x) -{ /* Used internally */ - uint32 Xl; - uint32 Xr, temp; - short i; - - Xl = x[0]; - Xr = x[1]; - - for (i = 0; i < BF_N; ++i) { - Xl ^= c->P[i]; - Xr ^= F(c, Xl); - - temp = Xl; - Xl = Xr; - Xr = temp; - } - - temp = Xl; - Xl = Xr; - Xr = temp; - - Xr ^= c->P[BF_N]; - Xl ^= c->P[BF_N + 1]; - - x[0] = Xl; - x[1] = Xr; -} - - -/* salt is an 128 bit integer */ -static short initialize_blowfish(blf_ctx * c) -{ - short i; - - uint32 ks0[] = { - 0xd1310ba6UL, 0x98dfb5acUL, 0x2ffd72dbUL, 0xd01adfb7UL, - 0xb8e1afedUL, 0x6a267e96UL, - 0xba7c9045UL, 0xf12c7f99UL, 0x24a19947UL, 0xb3916cf7UL, - 0x0801f2e2UL, 0x858efc16UL, - 0x636920d8UL, 0x71574e69UL, 0xa458fea3UL, 0xf4933d7eUL, - 0x0d95748fUL, 0x728eb658UL, - 0x718bcd58UL, 0x82154aeeUL, 0x7b54a41dUL, 0xc25a59b5UL, - 0x9c30d539UL, 0x2af26013UL, - 0xc5d1b023UL, 0x286085f0UL, 0xca417918UL, 0xb8db38efUL, - 0x8e79dcb0UL, 0x603a180eUL, - 0x6c9e0e8bUL, 0xb01e8a3eUL, 0xd71577c1UL, 0xbd314b27UL, - 0x78af2fdaUL, 0x55605c60UL, - 0xe65525f3UL, 0xaa55ab94UL, 0x57489862UL, 0x63e81440UL, - 0x55ca396aUL, 0x2aab10b6UL, - 0xb4cc5c34UL, 0x1141e8ceUL, 0xa15486afUL, 0x7c72e993UL, - 0xb3ee1411UL, 0x636fbc2aUL, - 0x2ba9c55dUL, 0x741831f6UL, 0xce5c3e16UL, 0x9b87931eUL, - 0xafd6ba33UL, 0x6c24cf5cUL, - 0x7a325381UL, 0x28958677UL, 0x3b8f4898UL, 0x6b4bb9afUL, - 0xc4bfe81bUL, 0x66282193UL, - 0x61d809ccUL, 0xfb21a991UL, 0x487cac60UL, 0x5dec8032UL, - 0xef845d5dUL, 0xe98575b1UL, - 0xdc262302UL, 0xeb651b88UL, 0x23893e81UL, 0xd396acc5UL, - 0x0f6d6ff3UL, 0x83f44239UL, - 0x2e0b4482UL, 0xa4842004UL, 0x69c8f04aUL, 0x9e1f9b5eUL, - 0x21c66842UL, 0xf6e96c9aUL, - 0x670c9c61UL, 0xabd388f0UL, 0x6a51a0d2UL, 0xd8542f68UL, - 0x960fa728UL, 0xab5133a3UL, - 0x6eef0b6cUL, 0x137a3be4UL, 0xba3bf050UL, 0x7efb2a98UL, - 0xa1f1651dUL, 0x39af0176UL, - 0x66ca593eUL, 0x82430e88UL, 0x8cee8619UL, 0x456f9fb4UL, - 0x7d84a5c3UL, 0x3b8b5ebeUL, - 0xe06f75d8UL, 0x85c12073UL, 0x401a449fUL, 0x56c16aa6UL, - 0x4ed3aa62UL, 0x363f7706UL, - 0x1bfedf72UL, 0x429b023dUL, 0x37d0d724UL, 0xd00a1248UL, - 0xdb0fead3UL, 0x49f1c09bUL, - 0x075372c9UL, 0x80991b7bUL, 0x25d479d8UL, 0xf6e8def7UL, - 0xe3fe501aUL, 0xb6794c3bUL, - 0x976ce0bdUL, 0x04c006baUL, 0xc1a94fb6UL, 0x409f60c4UL, - 0x5e5c9ec2UL, 0x196a2463UL, - 0x68fb6fafUL, 0x3e6c53b5UL, 0x1339b2ebUL, 0x3b52ec6fUL, - 0x6dfc511fUL, 0x9b30952cUL, - 0xcc814544UL, 0xaf5ebd09UL, 0xbee3d004UL, 0xde334afdUL, - 0x660f2807UL, 0x192e4bb3UL, - 0xc0cba857UL, 0x45c8740fUL, 0xd20b5f39UL, 0xb9d3fbdbUL, - 0x5579c0bdUL, 0x1a60320aUL, - 0xd6a100c6UL, 0x402c7279UL, 0x679f25feUL, 0xfb1fa3ccUL, - 0x8ea5e9f8UL, 0xdb3222f8UL, - 0x3c7516dfUL, 0xfd616b15UL, 0x2f501ec8UL, 0xad0552abUL, - 0x323db5faUL, 0xfd238760UL, - 0x53317b48UL, 0x3e00df82UL, 0x9e5c57bbUL, 0xca6f8ca0UL, - 0x1a87562eUL, 0xdf1769dbUL, - 0xd542a8f6UL, 0x287effc3UL, 0xac6732c6UL, 0x8c4f5573UL, - 0x695b27b0UL, 0xbbca58c8UL, - 0xe1ffa35dUL, 0xb8f011a0UL, 0x10fa3d98UL, 0xfd2183b8UL, - 0x4afcb56cUL, 0x2dd1d35bUL, - 0x9a53e479UL, 0xb6f84565UL, 0xd28e49bcUL, 0x4bfb9790UL, - 0xe1ddf2daUL, 0xa4cb7e33UL, - 0x62fb1341UL, 0xcee4c6e8UL, 0xef20cadaUL, 0x36774c01UL, - 0xd07e9efeUL, 0x2bf11fb4UL, - 0x95dbda4dUL, 0xae909198UL, 0xeaad8e71UL, 0x6b93d5a0UL, - 0xd08ed1d0UL, 0xafc725e0UL, - 0x8e3c5b2fUL, 0x8e7594b7UL, 0x8ff6e2fbUL, 0xf2122b64UL, - 0x8888b812UL, 0x900df01cUL, - 0x4fad5ea0UL, 0x688fc31cUL, 0xd1cff191UL, 0xb3a8c1adUL, - 0x2f2f2218UL, 0xbe0e1777UL, - 0xea752dfeUL, 0x8b021fa1UL, 0xe5a0cc0fUL, 0xb56f74e8UL, - 0x18acf3d6UL, 0xce89e299UL, - 0xb4a84fe0UL, 0xfd13e0b7UL, 0x7cc43b81UL, 0xd2ada8d9UL, - 0x165fa266UL, 0x80957705UL, - 0x93cc7314UL, 0x211a1477UL, 0xe6ad2065UL, 0x77b5fa86UL, - 0xc75442f5UL, 0xfb9d35cfUL, - 0xebcdaf0cUL, 0x7b3e89a0UL, 0xd6411bd3UL, 0xae1e7e49UL, - 0x00250e2dUL, 0x2071b35eUL, - 0x226800bbUL, 0x57b8e0afUL, 0x2464369bUL, 0xf009b91eUL, - 0x5563911dUL, 0x59dfa6aaUL, - 0x78c14389UL, 0xd95a537fUL, 0x207d5ba2UL, 0x02e5b9c5UL, - 0x83260376UL, 0x6295cfa9UL, - 0x11c81968UL, 0x4e734a41UL, 0xb3472dcaUL, 0x7b14a94aUL, - 0x1b510052UL, 0x9a532915UL, - 0xd60f573fUL, 0xbc9bc6e4UL, 0x2b60a476UL, 0x81e67400UL, - 0x08ba6fb5UL, 0x571be91fUL, - 0xf296ec6bUL, 0x2a0dd915UL, 0xb6636521UL, 0xe7b9f9b6UL, - 0xff34052eUL, 0xc5855664UL, - 0x53b02d5dUL, 0xa99f8fa1UL, 0x08ba4799UL, 0x6e85076aUL - }; - - uint32 ks1[] = { - 0x4b7a70e9UL, 0xb5b32944UL, 0xdb75092eUL, 0xc4192623UL, - 0xad6ea6b0UL, 0x49a7df7dUL, - 0x9cee60b8UL, 0x8fedb266UL, 0xecaa8c71UL, 0x699a17ffUL, - 0x5664526cUL, 0xc2b19ee1UL, - 0x193602a5UL, 0x75094c29UL, 0xa0591340UL, 0xe4183a3eUL, - 0x3f54989aUL, 0x5b429d65UL, - 0x6b8fe4d6UL, 0x99f73fd6UL, 0xa1d29c07UL, 0xefe830f5UL, - 0x4d2d38e6UL, 0xf0255dc1UL, - 0x4cdd2086UL, 0x8470eb26UL, 0x6382e9c6UL, 0x021ecc5eUL, - 0x09686b3fUL, 0x3ebaefc9UL, - 0x3c971814UL, 0x6b6a70a1UL, 0x687f3584UL, 0x52a0e286UL, - 0xb79c5305UL, 0xaa500737UL, - 0x3e07841cUL, 0x7fdeae5cUL, 0x8e7d44ecUL, 0x5716f2b8UL, - 0xb03ada37UL, 0xf0500c0dUL, - 0xf01c1f04UL, 0x0200b3ffUL, 0xae0cf51aUL, 0x3cb574b2UL, - 0x25837a58UL, 0xdc0921bdUL, - 0xd19113f9UL, 0x7ca92ff6UL, 0x94324773UL, 0x22f54701UL, - 0x3ae5e581UL, 0x37c2dadcUL, - 0xc8b57634UL, 0x9af3dda7UL, 0xa9446146UL, 0x0fd0030eUL, - 0xecc8c73eUL, 0xa4751e41UL, - 0xe238cd99UL, 0x3bea0e2fUL, 0x3280bba1UL, 0x183eb331UL, - 0x4e548b38UL, 0x4f6db908UL, - 0x6f420d03UL, 0xf60a04bfUL, 0x2cb81290UL, 0x24977c79UL, - 0x5679b072UL, 0xbcaf89afUL, - 0xde9a771fUL, 0xd9930810UL, 0xb38bae12UL, 0xdccf3f2eUL, - 0x5512721fUL, 0x2e6b7124UL, - 0x501adde6UL, 0x9f84cd87UL, 0x7a584718UL, 0x7408da17UL, - 0xbc9f9abcUL, 0xe94b7d8cUL, - 0xec7aec3aUL, 0xdb851dfaUL, 0x63094366UL, 0xc464c3d2UL, - 0xef1c1847UL, 0x3215d908UL, - 0xdd433b37UL, 0x24c2ba16UL, 0x12a14d43UL, 0x2a65c451UL, - 0x50940002UL, 0x133ae4ddUL, - 0x71dff89eUL, 0x10314e55UL, 0x81ac77d6UL, 0x5f11199bUL, - 0x043556f1UL, 0xd7a3c76bUL, - 0x3c11183bUL, 0x5924a509UL, 0xf28fe6edUL, 0x97f1fbfaUL, - 0x9ebabf2cUL, 0x1e153c6eUL, - 0x86e34570UL, 0xeae96fb1UL, 0x860e5e0aUL, 0x5a3e2ab3UL, - 0x771fe71cUL, 0x4e3d06faUL, - 0x2965dcb9UL, 0x99e71d0fUL, 0x803e89d6UL, 0x5266c825UL, - 0x2e4cc978UL, 0x9c10b36aUL, - 0xc6150ebaUL, 0x94e2ea78UL, 0xa5fc3c53UL, 0x1e0a2df4UL, - 0xf2f74ea7UL, 0x361d2b3dUL, - 0x1939260fUL, 0x19c27960UL, 0x5223a708UL, 0xf71312b6UL, - 0xebadfe6eUL, 0xeac31f66UL, - 0xe3bc4595UL, 0xa67bc883UL, 0xb17f37d1UL, 0x018cff28UL, - 0xc332ddefUL, 0xbe6c5aa5UL, - 0x65582185UL, 0x68ab9802UL, 0xeecea50fUL, 0xdb2f953bUL, - 0x2aef7dadUL, 0x5b6e2f84UL, - 0x1521b628UL, 0x29076170UL, 0xecdd4775UL, 0x619f1510UL, - 0x13cca830UL, 0xeb61bd96UL, - 0x0334fe1eUL, 0xaa0363cfUL, 0xb5735c90UL, 0x4c70a239UL, - 0xd59e9e0bUL, 0xcbaade14UL, - 0xeecc86bcUL, 0x60622ca7UL, 0x9cab5cabUL, 0xb2f3846eUL, - 0x648b1eafUL, 0x19bdf0caUL, - 0xa02369b9UL, 0x655abb50UL, 0x40685a32UL, 0x3c2ab4b3UL, - 0x319ee9d5UL, 0xc021b8f7UL, - 0x9b540b19UL, 0x875fa099UL, 0x95f7997eUL, 0x623d7da8UL, - 0xf837889aUL, 0x97e32d77UL, - 0x11ed935fUL, 0x16681281UL, 0x0e358829UL, 0xc7e61fd6UL, - 0x96dedfa1UL, 0x7858ba99UL, - 0x57f584a5UL, 0x1b227263UL, 0x9b83c3ffUL, 0x1ac24696UL, - 0xcdb30aebUL, 0x532e3054UL, - 0x8fd948e4UL, 0x6dbc3128UL, 0x58ebf2efUL, 0x34c6ffeaUL, - 0xfe28ed61UL, 0xee7c3c73UL, - 0x5d4a14d9UL, 0xe864b7e3UL, 0x42105d14UL, 0x203e13e0UL, - 0x45eee2b6UL, 0xa3aaabeaUL, - 0xdb6c4f15UL, 0xfacb4fd0UL, 0xc742f442UL, 0xef6abbb5UL, - 0x654f3b1dUL, 0x41cd2105UL, - 0xd81e799eUL, 0x86854dc7UL, 0xe44b476aUL, 0x3d816250UL, - 0xcf62a1f2UL, 0x5b8d2646UL, - 0xfc8883a0UL, 0xc1c7b6a3UL, 0x7f1524c3UL, 0x69cb7492UL, - 0x47848a0bUL, 0x5692b285UL, - 0x095bbf00UL, 0xad19489dUL, 0x1462b174UL, 0x23820e00UL, - 0x58428d2aUL, 0x0c55f5eaUL, - 0x1dadf43eUL, 0x233f7061UL, 0x3372f092UL, 0x8d937e41UL, - 0xd65fecf1UL, 0x6c223bdbUL, - 0x7cde3759UL, 0xcbee7460UL, 0x4085f2a7UL, 0xce77326eUL, - 0xa6078084UL, 0x19f8509eUL, - 0xe8efd855UL, 0x61d99735UL, 0xa969a7aaUL, 0xc50c06c2UL, - 0x5a04abfcUL, 0x800bcadcUL, - 0x9e447a2eUL, 0xc3453484UL, 0xfdd56705UL, 0x0e1e9ec9UL, - 0xdb73dbd3UL, 0x105588cdUL, - 0x675fda79UL, 0xe3674340UL, 0xc5c43465UL, 0x713e38d8UL, - 0x3d28f89eUL, 0xf16dff20UL, - 0x153e21e7UL, 0x8fb03d4aUL, 0xe6e39f2bUL, 0xdb83adf7UL - }; - - uint32 ks2[] = { - 0xe93d5a68UL, 0x948140f7UL, 0xf64c261cUL, 0x94692934UL, - 0x411520f7UL, 0x7602d4f7UL, - 0xbcf46b2eUL, 0xd4a20068UL, 0xd4082471UL, 0x3320f46aUL, - 0x43b7d4b7UL, 0x500061afUL, - 0x1e39f62eUL, 0x97244546UL, 0x14214f74UL, 0xbf8b8840UL, - 0x4d95fc1dUL, 0x96b591afUL, - 0x70f4ddd3UL, 0x66a02f45UL, 0xbfbc09ecUL, 0x03bd9785UL, - 0x7fac6dd0UL, 0x31cb8504UL, - 0x96eb27b3UL, 0x55fd3941UL, 0xda2547e6UL, 0xabca0a9aUL, - 0x28507825UL, 0x530429f4UL, - 0x0a2c86daUL, 0xe9b66dfbUL, 0x68dc1462UL, 0xd7486900UL, - 0x680ec0a4UL, 0x27a18deeUL, - 0x4f3ffea2UL, 0xe887ad8cUL, 0xb58ce006UL, 0x7af4d6b6UL, - 0xaace1e7cUL, 0xd3375fecUL, - 0xce78a399UL, 0x406b2a42UL, 0x20fe9e35UL, 0xd9f385b9UL, - 0xee39d7abUL, 0x3b124e8bUL, - 0x1dc9faf7UL, 0x4b6d1856UL, 0x26a36631UL, 0xeae397b2UL, - 0x3a6efa74UL, 0xdd5b4332UL, - 0x6841e7f7UL, 0xca7820fbUL, 0xfb0af54eUL, 0xd8feb397UL, - 0x454056acUL, 0xba489527UL, - 0x55533a3aUL, 0x20838d87UL, 0xfe6ba9b7UL, 0xd096954bUL, - 0x55a867bcUL, 0xa1159a58UL, - 0xcca92963UL, 0x99e1db33UL, 0xa62a4a56UL, 0x3f3125f9UL, - 0x5ef47e1cUL, 0x9029317cUL, - 0xfdf8e802UL, 0x04272f70UL, 0x80bb155cUL, 0x05282ce3UL, - 0x95c11548UL, 0xe4c66d22UL, - 0x48c1133fUL, 0xc70f86dcUL, 0x07f9c9eeUL, 0x41041f0fUL, - 0x404779a4UL, 0x5d886e17UL, - 0x325f51ebUL, 0xd59bc0d1UL, 0xf2bcc18fUL, 0x41113564UL, - 0x257b7834UL, 0x602a9c60UL, - 0xdff8e8a3UL, 0x1f636c1bUL, 0x0e12b4c2UL, 0x02e1329eUL, - 0xaf664fd1UL, 0xcad18115UL, - 0x6b2395e0UL, 0x333e92e1UL, 0x3b240b62UL, 0xeebeb922UL, - 0x85b2a20eUL, 0xe6ba0d99UL, - 0xde720c8cUL, 0x2da2f728UL, 0xd0127845UL, 0x95b794fdUL, - 0x647d0862UL, 0xe7ccf5f0UL, - 0x5449a36fUL, 0x877d48faUL, 0xc39dfd27UL, 0xf33e8d1eUL, - 0x0a476341UL, 0x992eff74UL, - 0x3a6f6eabUL, 0xf4f8fd37UL, 0xa812dc60UL, 0xa1ebddf8UL, - 0x991be14cUL, 0xdb6e6b0dUL, - 0xc67b5510UL, 0x6d672c37UL, 0x2765d43bUL, 0xdcd0e804UL, - 0xf1290dc7UL, 0xcc00ffa3UL, - 0xb5390f92UL, 0x690fed0bUL, 0x667b9ffbUL, 0xcedb7d9cUL, - 0xa091cf0bUL, 0xd9155ea3UL, - 0xbb132f88UL, 0x515bad24UL, 0x7b9479bfUL, 0x763bd6ebUL, - 0x37392eb3UL, 0xcc115979UL, - 0x8026e297UL, 0xf42e312dUL, 0x6842ada7UL, 0xc66a2b3bUL, - 0x12754cccUL, 0x782ef11cUL, - 0x6a124237UL, 0xb79251e7UL, 0x06a1bbe6UL, 0x4bfb6350UL, - 0x1a6b1018UL, 0x11caedfaUL, - 0x3d25bdd8UL, 0xe2e1c3c9UL, 0x44421659UL, 0x0a121386UL, - 0xd90cec6eUL, 0xd5abea2aUL, - 0x64af674eUL, 0xda86a85fUL, 0xbebfe988UL, 0x64e4c3feUL, - 0x9dbc8057UL, 0xf0f7c086UL, - 0x60787bf8UL, 0x6003604dUL, 0xd1fd8346UL, 0xf6381fb0UL, - 0x7745ae04UL, 0xd736fcccUL, - 0x83426b33UL, 0xf01eab71UL, 0xb0804187UL, 0x3c005e5fUL, - 0x77a057beUL, 0xbde8ae24UL, - 0x55464299UL, 0xbf582e61UL, 0x4e58f48fUL, 0xf2ddfda2UL, - 0xf474ef38UL, 0x8789bdc2UL, - 0x5366f9c3UL, 0xc8b38e74UL, 0xb475f255UL, 0x46fcd9b9UL, - 0x7aeb2661UL, 0x8b1ddf84UL, - 0x846a0e79UL, 0x915f95e2UL, 0x466e598eUL, 0x20b45770UL, - 0x8cd55591UL, 0xc902de4cUL, - 0xb90bace1UL, 0xbb8205d0UL, 0x11a86248UL, 0x7574a99eUL, - 0xb77f19b6UL, 0xe0a9dc09UL, - 0x662d09a1UL, 0xc4324633UL, 0xe85a1f02UL, 0x09f0be8cUL, - 0x4a99a025UL, 0x1d6efe10UL, - 0x1ab93d1dUL, 0x0ba5a4dfUL, 0xa186f20fUL, 0x2868f169UL, - 0xdcb7da83UL, 0x573906feUL, - 0xa1e2ce9bUL, 0x4fcd7f52UL, 0x50115e01UL, 0xa70683faUL, - 0xa002b5c4UL, 0x0de6d027UL, - 0x9af88c27UL, 0x773f8641UL, 0xc3604c06UL, 0x61a806b5UL, - 0xf0177a28UL, 0xc0f586e0UL, - 0x006058aaUL, 0x30dc7d62UL, 0x11e69ed7UL, 0x2338ea63UL, - 0x53c2dd94UL, 0xc2c21634UL, - 0xbbcbee56UL, 0x90bcb6deUL, 0xebfc7da1UL, 0xce591d76UL, - 0x6f05e409UL, 0x4b7c0188UL, - 0x39720a3dUL, 0x7c927c24UL, 0x86e3725fUL, 0x724d9db9UL, - 0x1ac15bb4UL, 0xd39eb8fcUL, - 0xed545578UL, 0x08fca5b5UL, 0xd83d7cd3UL, 0x4dad0fc4UL, - 0x1e50ef5eUL, 0xb161e6f8UL, - 0xa28514d9UL, 0x6c51133cUL, 0x6fd5c7e7UL, 0x56e14ec4UL, - 0x362abfceUL, 0xddc6c837UL, - 0xd79a3234UL, 0x92638212UL, 0x670efa8eUL, 0x406000e0UL - }; - - uint32 ks3[] = { - 0x3a39ce37UL, 0xd3faf5cfUL, 0xabc27737UL, 0x5ac52d1bUL, - 0x5cb0679eUL, 0x4fa33742UL, - 0xd3822740UL, 0x99bc9bbeUL, 0xd5118e9dUL, 0xbf0f7315UL, - 0xd62d1c7eUL, 0xc700c47bUL, - 0xb78c1b6bUL, 0x21a19045UL, 0xb26eb1beUL, 0x6a366eb4UL, - 0x5748ab2fUL, 0xbc946e79UL, - 0xc6a376d2UL, 0x6549c2c8UL, 0x530ff8eeUL, 0x468dde7dUL, - 0xd5730a1dUL, 0x4cd04dc6UL, - 0x2939bbdbUL, 0xa9ba4650UL, 0xac9526e8UL, 0xbe5ee304UL, - 0xa1fad5f0UL, 0x6a2d519aUL, - 0x63ef8ce2UL, 0x9a86ee22UL, 0xc089c2b8UL, 0x43242ef6UL, - 0xa51e03aaUL, 0x9cf2d0a4UL, - 0x83c061baUL, 0x9be96a4dUL, 0x8fe51550UL, 0xba645bd6UL, - 0x2826a2f9UL, 0xa73a3ae1UL, - 0x4ba99586UL, 0xef5562e9UL, 0xc72fefd3UL, 0xf752f7daUL, - 0x3f046f69UL, 0x77fa0a59UL, - 0x80e4a915UL, 0x87b08601UL, 0x9b09e6adUL, 0x3b3ee593UL, - 0xe990fd5aUL, 0x9e34d797UL, - 0x2cf0b7d9UL, 0x022b8b51UL, 0x96d5ac3aUL, 0x017da67dUL, - 0xd1cf3ed6UL, 0x7c7d2d28UL, - 0x1f9f25cfUL, 0xadf2b89bUL, 0x5ad6b472UL, 0x5a88f54cUL, - 0xe029ac71UL, 0xe019a5e6UL, - 0x47b0acfdUL, 0xed93fa9bUL, 0xe8d3c48dUL, 0x283b57ccUL, - 0xf8d56629UL, 0x79132e28UL, - 0x785f0191UL, 0xed756055UL, 0xf7960e44UL, 0xe3d35e8cUL, - 0x15056dd4UL, 0x88f46dbaUL, - 0x03a16125UL, 0x0564f0bdUL, 0xc3eb9e15UL, 0x3c9057a2UL, - 0x97271aecUL, 0xa93a072aUL, - 0x1b3f6d9bUL, 0x1e6321f5UL, 0xf59c66fbUL, 0x26dcf319UL, - 0x7533d928UL, 0xb155fdf5UL, - 0x03563482UL, 0x8aba3cbbUL, 0x28517711UL, 0xc20ad9f8UL, - 0xabcc5167UL, 0xccad925fUL, - 0x4de81751UL, 0x3830dc8eUL, 0x379d5862UL, 0x9320f991UL, - 0xea7a90c2UL, 0xfb3e7bceUL, - 0x5121ce64UL, 0x774fbe32UL, 0xa8b6e37eUL, 0xc3293d46UL, - 0x48de5369UL, 0x6413e680UL, - 0xa2ae0810UL, 0xdd6db224UL, 0x69852dfdUL, 0x09072166UL, - 0xb39a460aUL, 0x6445c0ddUL, - 0x586cdecfUL, 0x1c20c8aeUL, 0x5bbef7ddUL, 0x1b588d40UL, - 0xccd2017fUL, 0x6bb4e3bbUL, - 0xdda26a7eUL, 0x3a59ff45UL, 0x3e350a44UL, 0xbcb4cdd5UL, - 0x72eacea8UL, 0xfa6484bbUL, - 0x8d6612aeUL, 0xbf3c6f47UL, 0xd29be463UL, 0x542f5d9eUL, - 0xaec2771bUL, 0xf64e6370UL, - 0x740e0d8dUL, 0xe75b1357UL, 0xf8721671UL, 0xaf537d5dUL, - 0x4040cb08UL, 0x4eb4e2ccUL, - 0x34d2466aUL, 0x0115af84UL, 0xe1b00428UL, 0x95983a1dUL, - 0x06b89fb4UL, 0xce6ea048UL, - 0x6f3f3b82UL, 0x3520ab82UL, 0x011a1d4bUL, 0x277227f8UL, - 0x611560b1UL, 0xe7933fdcUL, - 0xbb3a792bUL, 0x344525bdUL, 0xa08839e1UL, 0x51ce794bUL, - 0x2f32c9b7UL, 0xa01fbac9UL, - 0xe01cc87eUL, 0xbcc7d1f6UL, 0xcf0111c3UL, 0xa1e8aac7UL, - 0x1a908749UL, 0xd44fbd9aUL, - 0xd0dadecbUL, 0xd50ada38UL, 0x0339c32aUL, 0xc6913667UL, - 0x8df9317cUL, 0xe0b12b4fUL, - 0xf79e59b7UL, 0x43f5bb3aUL, 0xf2d519ffUL, 0x27d9459cUL, - 0xbf97222cUL, 0x15e6fc2aUL, - 0x0f91fc71UL, 0x9b941525UL, 0xfae59361UL, 0xceb69cebUL, - 0xc2a86459UL, 0x12baa8d1UL, - 0xb6c1075eUL, 0xe3056a0cUL, 0x10d25065UL, 0xcb03a442UL, - 0xe0ec6e0eUL, 0x1698db3bUL, - 0x4c98a0beUL, 0x3278e964UL, 0x9f1f9532UL, 0xe0d392dfUL, - 0xd3a0342bUL, 0x8971f21eUL, - 0x1b0a7441UL, 0x4ba3348cUL, 0xc5be7120UL, 0xc37632d8UL, - 0xdf359f8dUL, 0x9b992f2eUL, - 0xe60b6f47UL, 0x0fe3f11dUL, 0xe54cda54UL, 0x1edad891UL, - 0xce6279cfUL, 0xcd3e7e6fUL, - 0x1618b166UL, 0xfd2c1d05UL, 0x848fd2c5UL, 0xf6fb2299UL, - 0xf523f357UL, 0xa6327623UL, - 0x93a83531UL, 0x56cccd02UL, 0xacf08162UL, 0x5a75ebb5UL, - 0x6e163697UL, 0x88d273ccUL, - 0xde966292UL, 0x81b949d0UL, 0x4c50901bUL, 0x71c65614UL, - 0xe6c6c7bdUL, 0x327a140aUL, - 0x45e1d006UL, 0xc3f27b9aUL, 0xc9aa53fdUL, 0x62a80f00UL, - 0xbb25bfe2UL, 0x35bdd2f6UL, - 0x71126905UL, 0xb2040222UL, 0xb6cbcf7cUL, 0xcd769c2bUL, - 0x53113ec0UL, 0x1640e3d3UL, - 0x38abbd60UL, 0x2547adf0UL, 0xba38209cUL, 0xf746ce76UL, - 0x77afa1c5UL, 0x20756060UL, - 0x85cbfe4eUL, 0x8ae88dd8UL, 0x7aaaf9b0UL, 0x4cf9aa7eUL, - 0x1948c25cUL, 0x02fb8a8cUL, - 0x01c36ae4UL, 0xd6ebe1f9UL, 0x90d4f869UL, 0xa65cdea0UL, - 0x3f09252dUL, 0xc208e69fUL, - 0xb74e6132UL, 0xce77e25bUL, 0x578fdfe3UL, 0x3ac372e6UL - }; - - - uint32 pi[] = { - 0x243f6a88UL, 0x85a308d3UL, 0x13198a2eUL, 0x03707344UL, - 0xa4093822UL, 0x299f31d0UL, - 0x082efa98UL, 0xec4e6c89UL, 0x452821e6UL, 0x38d01377UL, - 0xbe5466cfUL, 0x34e90c6cUL, - 0xc0ac29b7UL, 0xc97c50ddUL, 0x3f84d5b5UL, 0xb5470917UL, - 0x9216d5d9UL, 0x8979fb1bUL - }; - - -/* Initialize s-boxes without file read. */ - for (i = 0; i < 256; i++) { - c->S[0][i] = ks0[i]; - c->S[1][i] = ks1[i]; - c->S[2][i] = ks2[i]; - c->S[3][i] = ks3[i]; - } - -/* P-boxes */ - for (i = 0; i < 18; i++) { - c->P[i] = pi[i]; - } - return 0; -} - -static short _blf_ExpandKey(blf_ctx * c, const uint8 * key, short keybytes, - const uint8 * bsalt) -{ - short i, j; - int k; - uint32 data, temp[2]; - uint32 wsalt[4]; - - if (bsalt != NULL) { - wsalt[0] = 0x00000000; - wsalt[1] = 0x00000000; - wsalt[2] = 0x00000000; - wsalt[3] = 0x00000000; - for (i = 0; i < 4; i++) { - wsalt[0] = (wsalt[0] << 8) | bsalt[i]; - wsalt[1] = (wsalt[1] << 8) | bsalt[i + 4]; - wsalt[2] = (wsalt[2] << 8) | bsalt[i + 8]; - wsalt[3] = (wsalt[3] << 8) | bsalt[i + 12]; - } - } - - temp[0] = temp[1] = 0x00000000; - - j = 0; - /* Step 1: XOR the Pbox with the key */ - for (i = 0; i < BF_N + 2; i++) { - data = 0x00000000; - data = (data << 8) | key[(j) % keybytes]; - data = (data << 8) | key[(j + 1) % keybytes]; - data = (data << 8) | key[(j + 2) % keybytes]; - data = (data << 8) | key[(j + 3) % keybytes]; - - c->P[i] ^= data; - j = (j + 4) % keybytes; - } - - k = 2; /* This should be 0 ??? */ - /* Step 2: Use the salt on Pbox */ - for (i = 0; i < BF_N + 2; i += 2) { - if (bsalt != NULL) { - temp[0] ^= wsalt[(k + 2) % 4]; - temp[1] ^= wsalt[(k + 3) % 4]; - k = (k + 2) % 4; - } - enblf_noswap(c, temp); - c->P[i] = temp[0]; - c->P[i + 1] = temp[1]; - } - - for (i = 0; i < 4; i++) { - for (j = 0; j < 256; j += 2) { - if (bsalt != NULL) { - temp[0] ^= wsalt[(k + 2) % 4]; - temp[1] ^= wsalt[(k + 3) % 4]; - k = (k + 2) % 4; - } - enblf_noswap(c, temp); - c->S[i][j] = temp[0]; - c->S[i][j + 1] = temp[1]; - - } - } - return 0; -} - - - - -static blf_ctx *_blf_init(uint8 * salt, const char *key, int key_len, - int cost) -{ - blf_ctx *state = gnutls_malloc(sizeof(blf_ctx)); - uint32 i, rcost; - - if (state==NULL) - return NULL; - - rcost = (uint32) 1 << cost; /* 2^cost */ - - initialize_blowfish(state); - _blf_ExpandKey(state, (uint8 *) key, key_len, salt); - for (i = 0; i < rcost; i++) { - /* these should have been in reverse order */ - _blf_ExpandKey(state, (uint8 *) key, key_len, NULL); - _blf_ExpandKey(state, salt, 16, NULL); - } - return state; -} - -static void _blf_deinit(blf_ctx * ctx) -{ - gnutls_free(ctx); -} -static const char magic[] = "$2$"; - -#define B64TEXT "OrpheanBeholderScryDoubt" - -char *crypt_bcrypt(const char* username, const char *passwd, const char *salt, GNUTLS_MPI g, GNUTLS_MPI n) -{ - unsigned char *sp; - blf_ctx *ctx; - unsigned char text[24]; - uint8 *csalt; - uint8 *rtext; - uint8 cost; - int i, salt_size = strlen(salt), len; - unsigned char *local_salt, *v; - int passwd_len, vsize, tmpsize; - opaque *tmp; - - /* copy username+null+B64TEXT to text */ - strncpy( text, username, sizeof(text)); - if ( ( sizeof(text)-strlen(username) - 1 ) > 0) - strncpy( &text[strlen(username)+1], B64TEXT, sizeof(text)-strlen(username)-1); - - passwd_len = strlen(passwd) + 1; /* we want the null also */ - if (passwd_len > 56) - passwd_len = 56; - - local_salt = gnutls_malloc(salt_size + 1); - if (local_salt==NULL) { - gnutls_assert(); - return NULL; - } - strcpy((char *) local_salt, salt); /* Flawfinder: ignore */ - - sp = index( local_salt, ':'); /* move to salt - after verifier */ - if (sp==NULL) { - gnutls_assert(); - return NULL; - } - sp++; - - len = (int)rindex(sp, ':'); - if (len==0) { /* no ':' was found */ - len = strlen(sp); - } else - len -= (int) sp; - - if (_gnutls_sbase64_decode(sp, len, &csalt) < 0) { - gnutls_assert(); - return NULL; - } - - cost = (int) csalt[0]; - ctx = _blf_init(&csalt[1], passwd, passwd_len, cost); - gnutls_free(csalt); - - if (ctx==NULL) { - return NULL; - } - - for (i = 0; i < 64; i++) { - _blf_encrypt(ctx, (uint8 *) text); - _blf_encrypt(ctx, (uint8 *) & text[8]); - _blf_encrypt(ctx, (uint8 *) & text[16]); - } - - /* v = g^x mod n */ - vsize = _gnutls_srp_gx(text, 8 * 3, &v, g, n); - if (vsize == -1 || v == NULL) { - gnutls_assert(); - return NULL; - } - - if (_gnutls_sbase64_encode(v, vsize, &rtext) < 0) { - gnutls_free(v); - gnutls_assert(); - return NULL; - } - gnutls_free(v); - - tmpsize = strlen(magic) + 3 + strlen(sp) + 1 + strlen(rtext) + 1; - tmp = - gnutls_malloc( tmpsize); - if (tmp==NULL) { - gnutls_assert(); - return NULL; - } - - sprintf(tmp, "%s%s:%s", magic, rtext, sp); /* Flawfinder: ignore */ - - gnutls_free(local_salt); - gnutls_free(rtext); - - _blf_deinit(ctx); - return tmp; -} - -/* cost is stored as the first byte in salt (thus < 255) which is - * just fine! - */ -char *crypt_bcrypt_wrapper(const char* username, const char *pass_new, int cost, GNUTLS_MPI g, GNUTLS_MPI n) -{ - opaque *result; - char *tcp; - uint8 rand[17]; - char *e = NULL; - int result_size; - - if (_gnutls_get_random(&rand[1], 17, GNUTLS_WEAK_RANDOM) < 0 ) { - gnutls_assert(); - return NULL; - } - /* cost should be <32 and >6 */ - if (cost >= 32) - cost = 31; - if (cost < 1) - cost = 1; - - rand[0] = (uint8) cost; - result_size = _gnutls_sbase64_encode( rand, 17, &result); - - if (result_size < 0) { - gnutls_assert(); - return NULL; - } - - tcp = gnutls_calloc(1, 1 + result_size + 1); - sprintf(tcp, ":%s", result); /* Flawfinder: ignore */ - - gnutls_free(result); - - - e = crypt_bcrypt(username, pass_new, (const char *) tcp, g, n); - gnutls_free(tcp); - - return e; -} - -#define BCRYPT_SIZE 24 -int _gnutls_calc_srp_bcrypt(const char* username, const char *passwd, opaque * salt, int salt_size, int* size, void* digest) -{ - blf_ctx *ctx; - opaque text[BCRYPT_SIZE]; - int passwd_len, i; - - strncpy( text, username, sizeof(text)); - if ( (sizeof(text)-strlen(username)-1) > 0) - strncpy( &text[strlen(username)+1], B64TEXT, sizeof(text)-strlen(username)-1); - - *size = sizeof(text); - - /* we need 16 + cost */ - if (salt_size < 17) return -1; - - passwd_len = strlen(passwd) + 1; /* we want the null also */ - if (passwd_len > 56) - passwd_len = 56; - - ctx = _blf_init(&salt[1], passwd, passwd_len, (int)(salt[0])); - if (ctx==NULL) { - return GNUTLS_E_MEMORY_ERROR; - } - - for (i = 0; i < 64; i++) { - _blf_encrypt(ctx, (uint8 *) text); - _blf_encrypt(ctx, (uint8 *) & text[8]); - _blf_encrypt(ctx, (uint8 *) & text[16]); - } - - _blf_deinit(ctx); - - memcpy( digest, text, BCRYPT_SIZE); - return 0; -} - -#endif /* ENABLE_SRP */ diff --git a/lib/crypt_bcrypt.h b/lib/crypt_bcrypt.h deleted file mode 100644 index 00458a2e2b..0000000000 --- a/lib/crypt_bcrypt.h +++ /dev/null @@ -1,3 +0,0 @@ -char * crypt_bcrypt (const char* username, const char *passwd, const char *salt, MPI g, MPI n); -char *crypt_bcrypt_wrapper(const char* username, const char *pass_new, int cost, MPI g, MPI n); -int _gnutls_calc_srp_bcrypt( const char* username, const char *passwd, opaque *salt, int salt_size, int* size, void* digest); diff --git a/lib/crypt_srpsha1.c b/lib/crypt_srpsha1.c deleted file mode 100644 index 0dbc5ff8e8..0000000000 --- a/lib/crypt_srpsha1.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2001 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * GNUTLS 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 2 of the License, or - * (at your option) any later version. - * - * GNUTLS 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "gnutls_int.h" - -#ifdef ENABLE_SRP - -#include "gnutls_random.h" -#include "gnutls_hash_int.h" -#include "auth_srp_passwd.h" -#include "gnutls_srp.h" -#include - -/* x = SHA( | SHA( | ":" | )) */ - -static const char magic[] = ""; - -char *crypt_srpsha1(const char *username, const char *passwd, - const char *salt, GNUTLS_MPI g, GNUTLS_MPI n) -{ - unsigned char *sp, r1[MAX_HASH_SIZE]; - int salt_size = strlen(salt); - unsigned char *local_salt, *v; - int passwd_len; - GNUTLS_HASH_HANDLE h1; - int vsize, hash_len = _gnutls_hash_get_algo_len(GNUTLS_MAC_SHA); - opaque *tmp; - uint8 *rtext, *csalt; - int rsalt_size, len, tmpsize; - - passwd_len = strlen(passwd); /* we do not want the null */ - - h1 = _gnutls_hash_init(GNUTLS_MAC_SHA); - _gnutls_hash(h1, (char *) username, strlen(username)); - _gnutls_hash(h1, ":", 1); - _gnutls_hash(h1, (char *) passwd, passwd_len); - _gnutls_hash_deinit(h1, r1); - - - local_salt = gnutls_malloc(salt_size + 1); - if (local_salt==NULL) { - gnutls_assert(); - return NULL; - } - strcpy((char *) local_salt, salt); /* Flawfinder: ignore */ - - sp = index( local_salt, ':'); /* move to salt - after verifier */ - if (sp==NULL) { - gnutls_assert(); - gnutls_free( local_salt); - return NULL; - } - sp++; - - len = (int)rindex(sp, ':'); - if (len==0) { /* parse error */ - len = strlen(sp); - } else - len -= (int)sp; - - rsalt_size = _gnutls_sbase64_decode(sp, len, &csalt); - if (rsalt_size < 0) { - gnutls_assert(); - gnutls_free(local_salt); - return NULL; - } - - h1 = _gnutls_hash_init(GNUTLS_MAC_SHA); - if (h1==NULL) { - gnutls_assert(); - gnutls_free(local_salt); - return NULL; - } - _gnutls_hash(h1, csalt, rsalt_size); - gnutls_free(csalt); - - _gnutls_hash(h1, r1, hash_len); - - _gnutls_hash_deinit(h1, r1); - - /* v = g^x mod n */ - vsize = _gnutls_srp_gx(r1, hash_len, &v, g, n); - - if (vsize == -1 || v == NULL) { - gnutls_assert(); - gnutls_free(local_salt); - return NULL; - } - - if (_gnutls_sbase64_encode(v, vsize, &rtext) < 0) { - gnutls_free(v); - gnutls_free(local_salt); - gnutls_assert(); - return NULL; - } - gnutls_free(v); - - tmpsize = strlen(sp) + strlen(rtext) + strlen(magic) + 1 + 1; - tmp = - gnutls_malloc( tmpsize); - if (tmp==NULL) { - gnutls_assert(); - gnutls_free(local_salt); - return NULL; - } - sprintf(tmp, "%s%s:%s", magic, rtext, sp); /* Flawfinder: ignore */ - - gnutls_free(rtext); - gnutls_free(local_salt); - - return tmp; -} - -/* salt here is the salt size */ -char *crypt_srpsha1_wrapper(const char *username, const char *pass_new, - int salt, GNUTLS_MPI g, GNUTLS_MPI n) -{ - unsigned char *result; - char *tcp; - opaque *rand; - char *e = NULL; - int result_size; - - if (salt > 50 || salt <= 0) - return NULL; /* wow that's pretty long salt */ - - rand = gnutls_malloc(salt); - if (rand==NULL || _gnutls_get_random(rand, salt, GNUTLS_WEAK_RANDOM) < 0) { - gnutls_assert(); - return NULL; - } - - result_size = _gnutls_sbase64_encode(rand, salt, &result); - if (result_size < 0) { - gnutls_free(rand); - gnutls_assert(); - return NULL; - } - - tcp = gnutls_calloc(1, 1+ result_size + 1); - if (tcp==NULL) { - gnutls_assert(); - gnutls_free(rand); - return NULL; - } - sprintf(tcp, ":%s", result); /* Flawfinder: ignore */ - - gnutls_free(result); - gnutls_free(rand); - /* no longer need cleartext */ - - e = crypt_srpsha1(username, pass_new, (const char *) tcp, g, n); - gnutls_free(tcp); - - return e; -} - -#endif diff --git a/lib/crypt_srpsha1.h b/lib/crypt_srpsha1.h deleted file mode 100644 index bf0d55ebbe..0000000000 --- a/lib/crypt_srpsha1.h +++ /dev/null @@ -1,2 +0,0 @@ -char * crypt_srpsha1(const char* username, const char *passwd, const char *salt, MPI g, MPI n); -char *crypt_srpsha1_wrapper(const char* username, const char *pass_new, int salt, MPI g, MPI n); diff --git a/lib/ext_srp.c b/lib/ext_srp.c deleted file mode 100644 index c04d5ced44..0000000000 --- a/lib/ext_srp.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2001,2002 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * GNUTLS 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 2 of the License, or - * (at your option) any later version. - * - * GNUTLS 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "gnutls_int.h" - -#ifdef ENABLE_SRP - -#include "gnutls_auth_int.h" -#include "auth_srp.h" -#include "gnutls_errors.h" -#include "gnutls_algorithms.h" - -int _gnutls_srp_recv_params( GNUTLS_STATE state, const opaque* data, int data_size) { - uint8 len; - - if (_gnutls_kx_priority( state, GNUTLS_KX_SRP) < 0) { - /* algorithm was not allowed in this state - */ - return 0; - } - - if (state->security_parameters.entity == GNUTLS_SERVER) { - if (data_size > 0) { - len = data[0]; - if (len > data_size) { - gnutls_assert(); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - if ( sizeof( state->security_parameters.extensions.srp_username) <= len) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - memcpy( state->security_parameters.extensions.srp_username, &data[1], len); - state->security_parameters.extensions.srp_username[len]=0; /* null terminated */ - } - } else { /* client side reading server hello extensions */ - if (state->gnutls_internals.resumed==RESUME_FALSE) - return proc_srp_server_hello( state, data, data_size); - else /* we do not need to process this if - * we are resuming. - */ - return 0; - } - return 0; -} - -/* returns data_size or a negative number on failure - * data is allocated localy - */ -int _gnutls_srp_send_params( GNUTLS_STATE state, opaque* data, int data_size) { - uint8 len; - - if (_gnutls_kx_priority( state, GNUTLS_KX_SRP) < 0) { - /* algorithm was not allowed in this state - */ - return 0; - } - - /* this function sends the client extension data (username) */ - if (state->security_parameters.entity == GNUTLS_CLIENT) { - const GNUTLS_SRP_CLIENT_CREDENTIALS cred = _gnutls_get_cred( state->gnutls_key, GNUTLS_CRD_SRP, NULL); - - if (cred==NULL) return 0; - - if (cred->username!=NULL) { /* send username */ - len = strlen(cred->username); - if (data_size < len+1) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - data[0] = len; - memcpy( &data[1], cred->username, len); - return len + 1; - } - } else { /* SERVER SIDE sending (g,n,s) */ - /* We only send the packet if we are NOT - * resuming AND we are using SRP - */ - - /* note that security parameters are not fully established - */ - if ( _gnutls_cipher_suite_get_kx_algo(state->security_parameters.current_cipher_suite) != GNUTLS_KX_SRP) - return 0; /* no data to send */ - - if (state->gnutls_internals.resumed==RESUME_FALSE) - return gen_srp_server_hello( state, data, data_size); - else - return 0; - } - return 0; -} - -#endif /* ENABLE_SRP */ diff --git a/lib/ext_srp.h b/lib/ext_srp.h deleted file mode 100644 index ae3158a693..0000000000 --- a/lib/ext_srp.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifdef ENABLE_SRP - -int _gnutls_srp_recv_params( GNUTLS_STATE state, const opaque* data, int data_size); -int _gnutls_srp_send_params( GNUTLS_STATE state, opaque* data, int); - -#endif diff --git a/lib/gnutls-extra.h b/lib/gnutls-extra.h deleted file mode 100644 index 6e06ce3db2..0000000000 --- a/lib/gnutls-extra.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2002 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * GNUTLS 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 2 of the License, or - * (at your option) any later version. - * - * GNUTLS 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUTLS_EXTRA_H -# define GNUTLS_EXTRA_H - -#include - -/* SRP */ - -typedef struct DSTRUCT* GNUTLS_SRP_SERVER_CREDENTIALS; -typedef struct DSTRUCT* GNUTLS_SRP_CLIENT_CREDENTIALS; - -void gnutls_srp_free_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS sc); -int gnutls_srp_allocate_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS *sc); -int gnutls_srp_set_client_cred( GNUTLS_SRP_CLIENT_CREDENTIALS res, char *username, char* password); - -void gnutls_srp_free_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS sc); -int gnutls_srp_allocate_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS *sc); -int gnutls_srp_set_server_cred_file( GNUTLS_SRP_SERVER_CREDENTIALS res, char *password_file, char* password_conf_file); - -const char* gnutls_srp_server_get_username( GNUTLS_STATE state); - -typedef int gnutls_srp_server_select_func(GNUTLS_STATE, char **, char**, int); - -void gnutls_srp_server_set_select_func( GNUTLS_STATE, gnutls_srp_server_select_func *); - -/* Openpgp certificate stuff */ -int gnutls_openpgp_extract_key_name( const gnutls_datum *cert, - int idx, - gnutls_openpgp_name *dn ); - -int gnutls_openpgp_extract_key_pk_algorithm(const gnutls_datum *cert, - int *r_bits); - -int gnutls_openpgp_extract_key_version( const gnutls_datum *cert ); - -time_t gnutls_openpgp_extract_key_creation_time( const gnutls_datum *cert ); -time_t gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert ); - -int gnutls_openpgp_verify_key( const gnutls_datum* keyring, - const gnutls_datum* key_list, - int key_list_length); - -int gnutls_certificate_set_openpgp_key_file( GNUTLS_CERTIFICATE_CREDENTIALS res, char *CERTFILE, char* KEYFILE); -int gnutls_certificate_set_openpgp_key_mem( GNUTLS_CERTIFICATE_CREDENTIALS res, - const gnutls_datum* CERT, const gnutls_datum* KEY); - -void gnutls_certificate_set_openpgp_keyserver(GNUTLS_CERTIFICATE_CREDENTIALS res, - char* keyserver, int port); - -void gnutls_certificate_set_openpgp_trustdb(GNUTLS_CERTIFICATE_CREDENTIALS res, - char* trustdb); - -int gnutls_certificate_set_openpgp_keyring_mem( GNUTLS_CERTIFICATE_CREDENTIALS res, - const char *data, size_t len); - -int gnutls_certificate_set_openpgp_keyring_file( GNUTLS_CERTIFICATE_CREDENTIALS res, const char *name); - -int gnutls_global_init_extra(void); - -#endif diff --git a/lib/gnutls_extra.c b/lib/gnutls_extra.c deleted file mode 100644 index a168d15552..0000000000 --- a/lib/gnutls_extra.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2002 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include - -extern gnutls_extension_entry _gnutls_extensions[]; -extern const int _gnutls_extensions_size; - -#define TOSTR(x) #x - -static int _gnutls_add_srp_extension(void) { -int i; - - /* find the last element */ - for(i=0;i<_gnutls_extensions_size;i++) { - if (_gnutls_extensions[i].name==NULL) break; - } - - if (_gnutls_extensions[i].name==NULL && (i < _gnutls_extensions_size-1)) { - _gnutls_extensions[i].name = TOSTR(GNUTLS_EXTENSION_SRP); - _gnutls_extensions[i].type = GNUTLS_EXTENSION_SRP; - _gnutls_extensions[i].gnutls_ext_func_recv = _gnutls_srp_recv_params; - _gnutls_extensions[i].gnutls_ext_func_send = _gnutls_srp_send_params; - - _gnutls_extensions[i+1].name = 0; - - return 0; /* ok */ - } - - return GNUTLS_E_MEMORY_ERROR; -} - -extern const int _gnutls_kx_algorithms_size; -extern gnutls_kx_algo_entry _gnutls_kx_algorithms[]; -extern MOD_AUTH_STRUCT srp_auth_struct; - -static int _gnutls_add_srp_auth_struct(void) { -int i; - - /* find the last element */ - for(i=0;i<_gnutls_kx_algorithms_size;i++) { - if (_gnutls_kx_algorithms[i].name==NULL) break; - } - - if (_gnutls_kx_algorithms[i].name==NULL && (i < _gnutls_kx_algorithms_size-1)) { - _gnutls_kx_algorithms[i].name = "SRP"; - _gnutls_kx_algorithms[i].algorithm = GNUTLS_KX_SRP; - _gnutls_kx_algorithms[i].auth_struct = &srp_auth_struct; - - _gnutls_kx_algorithms[i+1].name = 0; - - return 0; /* ok */ - } - - return GNUTLS_E_MEMORY_ERROR; -} - - -extern OPENPGP_KEY_CREATION_TIME_FUNC _E_gnutls_openpgp_extract_key_creation_time; -extern OPENPGP_KEY_EXPIRATION_TIME_FUNC _E_gnutls_openpgp_extract_key_expiration_time; -extern OPENPGP_VERIFY_KEY_FUNC _E_gnutls_openpgp_verify_key; -extern OPENPGP_CERT2GNUTLS_CERT _E_gnutls_openpgp_cert2gnutls_cert; -extern OPENPGP_FINGERPRINT _E_gnutls_openpgp_fingerprint; -extern OPENPGP_KEY_REQUEST _E_gnutls_openpgp_request_key; - -static void _gnutls_add_openpgp_functions(void) { - _E_gnutls_openpgp_verify_key = gnutls_openpgp_verify_key; - _E_gnutls_openpgp_extract_key_expiration_time = gnutls_openpgp_extract_key_expiration_time; - _E_gnutls_openpgp_extract_key_creation_time = gnutls_openpgp_extract_key_creation_time; - _E_gnutls_openpgp_fingerprint = gnutls_openpgp_fingerprint; - _E_gnutls_openpgp_request_key = _gnutls_openpgp_request_key; - _E_gnutls_openpgp_cert2gnutls_cert = _gnutls_openpgp_cert2gnutls_cert; - - return; -} - -static int _gnutls_init_extra = 0; - -/** - * gnutls_global_init_extra - This function initializes the global state of gnutls-extra - * - * This function initializes the global state of gnutls-extra library to defaults. - * Returns zero on success. - * - * Note that gnutls_global_init() has to be called before this function. - * If this function is not called then the gnutls-extra library will not - * be usable. - * - **/ -int gnutls_global_init_extra(void) { -int ret; - - _gnutls_init_extra++; - - if (_gnutls_init_extra!=1) { - return 0; - } - - ret = _gnutls_add_srp_auth_struct(); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - ret = _gnutls_add_srp_extension(); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - _gnutls_add_openpgp_functions(); - - return 0; -} diff --git a/lib/gnutls_extra.h b/lib/gnutls_extra.h deleted file mode 100644 index fba5882413..0000000000 --- a/lib/gnutls_extra.h +++ /dev/null @@ -1,9 +0,0 @@ -#include - -typedef int (*OPENPGP_VERIFY_KEY_FUNC)( const char *, - const gnutls_datum *, const gnutls_datum*, int); -typedef time_t (*OPENPGP_KEY_CREATION_TIME_FUNC)( const gnutls_datum*); -typedef time_t (*OPENPGP_KEY_EXPIRATION_TIME_FUNC)( const gnutls_datum*); -typedef int (*OPENPGP_KEY_REQUEST)(gnutls_datum*, const GNUTLS_CERTIFICATE_CREDENTIALS, opaque*,int); -typedef int (*OPENPGP_FINGERPRINT)(const gnutls_datum*, opaque*, size_t*); -typedef int (*OPENPGP_CERT2GNUTLS_CERT)(gnutls_cert*, gnutls_datum); diff --git a/lib/gnutls_openpgp.c b/lib/gnutls_openpgp.c deleted file mode 100644 index 3f0eea3347..0000000000 --- a/lib/gnutls_openpgp.c +++ /dev/null @@ -1,1702 +0,0 @@ -/* - * Copyright (C) 2002 Timo Schulz - * - * This file is part of GNUTLS. - * - * GNUTLS 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 2 of the License, or - * (at your option) any later version. - * - * GNUTLS 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "gnutls_int.h" -#include "gnutls_errors.h" -#include "gnutls_mpi.h" -#include "gnutls_cert.h" -#include "gnutls_datum.h" -#include "gnutls_global.h" -#include "auth_cert.h" -#include "gnutls_openpgp.h" - -#ifdef HAVE_LIBOPENCDK - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define OPENPGP_NAME_SIZE GNUTLS_X509_CN_SIZE - -typedef struct { - int type; - int armored; - size_t size; - byte *data; -} keybox_blob; - -typedef enum { - KBX_BLOB_FILE = 0x00, - KBX_BLOB_DATA = 0x01 -} keyring_blob_types; - -static void -release_mpi_array(GNUTLS_MPI *arr, size_t n) -{ - GNUTLS_MPI x; - - while ( arr && n-- ) - { - x = *arr; - _gnutls_mpi_release(&x); - *arr = NULL; arr++; - } -} - -static u32 -buffer_to_u32( const byte *buffer ) -{ - u32 u; - - if (!buffer) - return 0; - u = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]; - return u; -} - -static int -file_exist(const char *file) -{ - FILE *fp; - - if (!file) - return 0; - - fp = fopen(file, "r"); - if (fp) - { - fclose(fp); - return 1; - } - - return 0; -} - -static int -kbx_blob_new( keybox_blob **r_ctx ) -{ - keybox_blob *c; - - if ( !r_ctx ) - return GNUTLS_E_INVALID_PARAMETERS; - - c = cdk_alloc_clear( sizeof * c); - if ( !c ) - return GNUTLS_E_MEMORY_ERROR; - *r_ctx = c; - - return 0; -} /* kbx_blob_new */ - -static void -kbx_blob_release( keybox_blob *ctx ) -{ - if (!ctx) - return; - cdk_free(ctx->data); - cdk_free(ctx); -} /* kbx_blob_release */ - -static KEYDB_HD -kbx_to_keydb( keybox_blob *blob ) -{ - KEYDB_HD khd = NULL; - - if (!blob) - return NULL; - - khd = cdk_alloc_clear(sizeof *khd); - if ( !khd ) - return NULL; - khd->used = 1; - if ( blob->type == KBX_BLOB_FILE ) /* file */ - { - khd->name = cdk_strdup( blob->data ); - khd->type = blob->armored? KEYDB_TYPE_ARMORED: KEYDB_TYPE_KEYRING; - } - else if ( blob->type == KBX_BLOB_DATA ) /* data */ - { - cdk_iobuf_new( &khd->buf, blob->size ); - cdk_iobuf_write( khd->buf, blob->data, blob->size ); - khd->type = KEYDB_TYPE_DATA; - } - else /* error */ - { - cdk_free( khd ); - khd = NULL; - } - - return khd; -} /* kbx_to_keydb */ - -/* Extract a keybox blob from the given position. */ -static keybox_blob* -kbx_read_blob( const gnutls_datum* keyring, size_t pos ) -{ - keybox_blob *blob = NULL; - - if ( !keyring || !keyring->data ) - return NULL; - - if (pos > keyring->size) - return NULL; - - kbx_blob_new( &blob ); - blob->type = keyring->data[pos]; - if ( blob->type != KBX_BLOB_FILE && - blob->type != KBX_BLOB_DATA ) - { - kbx_blob_release( blob ); - return NULL; - } - blob->armored = keyring->data[pos+1]; - blob->size = buffer_to_u32( keyring->data+pos+2 ); - if (!blob->size) - { - kbx_blob_release( blob ); - return NULL; - } - blob->data = cdk_alloc_clear(blob->size + 1); - if ( !blob->data ) - return NULL; - memcpy(blob->data, keyring->data+(pos+6), blob->size); - blob->data[blob->size] = '\0'; - - return blob; -} /* kbx_read_blob */ - -/* Creates a keyring blob from raw data - * - * Format: - * 1 octet type - * 1 octet armored - * 4 octet size of blob - * n octets data - */ -static byte* -kbx_data_to_keyring( int type, int enc, const char *data, - size_t size, size_t *r_size ) -{ - byte *p = NULL; - - if (!data) - return NULL; - - p = gnutls_malloc( 1+4+size ); - if ( !p ) - return NULL; - p[0] = type; /* type: {keyring,name} */ - p[1] = enc; /* encoded: {plain, armored} */ - p[2] = (size >> 24) & 0xff; - p[3] = (size >> 16) & 0xff; - p[4] = (size >> 8) & 0xff; - p[5] = (size ) & 0xff; - memcpy( p+6, data, size ); - if ( r_size ) - *r_size = 6+size; - - return p; -} /* kbx_data_to_keyring */ - -static int -kbnode_to_datum( KBNODE kb_pk, gnutls_datum *raw ) -{ - KBNODE p = NULL; - byte *data = NULL; - size_t n = 0; - int rc = 0; - PACKET pkt = {0}; - IOBUF a; - - if (!kb_pk || !raw) - return GNUTLS_E_INVALID_PARAMETERS; - - /* fixme: conver the whole key */ - for (p=kb_pk; p && p->pkt->pkttype; p=p->next) - { - if (p->pkt->pkttype == PKT_PUBLIC_KEY) - { - a = cdk_iobuf_temp(); - pkt.pkttype = PKT_PUBLIC_KEY; - pkt.pkt.public_key = p->pkt->pkt.public_key; - rc = cdk_pkt_build( a, &pkt ); - if (rc) - return GNUTLS_E_UNKNOWN_ERROR; - data = cdk_iobuf_getdata(a, &n); - if (data && n) - { - rc = gnutls_set_datum(raw, data, n); - if (rc < 0) - return GNUTLS_E_MEMORY_ERROR; - } - cdk_free(data); - cdk_iobuf_close(a); - } - } - - return 0; -} - -static int -datum_to_kbnode( const gnutls_datum *raw, KBNODE *r_pkt ) -{ - IOBUF buf; - KBNODE pkt = NULL; - int dummy = 0; - int rc = 0; - - if (!raw || !r_pkt) - return GNUTLS_E_INVALID_PARAMETERS; - - cdk_iobuf_new( &buf, raw->size ); - cdk_iobuf_write( buf, raw->data, raw->size ); - rc = cdk_keydb_get_keyblock( buf, &pkt, &dummy ); - if ( rc && rc != CDKERR_EOF ) - { - rc = GNUTLS_E_NO_CERTIFICATE_FOUND; - goto leave; - } - else - rc = 0; - -leave: - cdk_iobuf_close( buf ); - *r_pkt = (!rc)? pkt : NULL; - - return rc; -} - -static int -iobuf_to_datum(IOBUF buf, gnutls_datum *raw) -{ - byte *data = NULL; - size_t nbytes = 0; - int rc = 0; - - if (!buf || !raw) - return GNUTLS_E_INVALID_PARAMETERS; - - data = cdk_iobuf_getdata(buf, &nbytes); - if (data && nbytes) - { - rc = gnutls_set_datum(raw, data, nbytes); - if (rc < 0) - return GNUTLS_E_MEMORY_ERROR; - cdk_free(data); - } - else - rc = GNUTLS_E_UNKNOWN_ERROR; - - return rc; -} - -static int -openpgp_pk_to_gnutls_cert(gnutls_cert *cert, PKT_public_key *pk) -{ - int algo, i; - int rc = 0; - size_t nbytes = 0; - - if (!cert || !pk) - return GNUTLS_E_INVALID_PARAMETERS; - - if ( is_ELG(pk->pubkey_algo) ) /* GnuTLS OpenPGP doesn't support ELG keys */ - return GNUTLS_E_UNWANTED_ALGORITHM; - - algo = is_DSA(pk->pubkey_algo)? GNUTLS_PK_DSA : GNUTLS_PK_RSA; - cert->subject_pk_algorithm = algo; - cert->version = pk->version; - cert->valid = 0; /* fixme: should set after the verification */ - cert->cert_type = GNUTLS_CRT_OPENPGP; - - if (is_DSA(pk->pubkey_algo) || pk->pubkey_algo == GCRY_PK_RSA_S) - cert->keyUsage = GNUTLS_X509KEY_DIGITAL_SIGNATURE; - else if (pk->pubkey_algo == GCRY_PK_RSA_E) - cert->keyUsage = GNUTLS_X509KEY_ENCIPHER_ONLY; - else if (pk->pubkey_algo == GCRY_PK_RSA) - cert->keyUsage = GNUTLS_X509KEY_DIGITAL_SIGNATURE - | GNUTLS_X509KEY_ENCIPHER_ONLY; - - cert->params_size = cdk_pk_get_npkey( pk->pubkey_algo ); - for (i=0; iparams_size; i++) - { - nbytes = pk->mpi[i].bytes+2; - rc = _gnutls_mpi_scan_pgp(&cert->params[i], - pk->mpi[i].data, &nbytes); - if (rc) - { - rc = GNUTLS_E_MPI_SCAN_FAILED; - goto leave; - } - } - cert->expiration_time = pk->expiredate; - cert->activation_time = pk->timestamp; - -leave: - if (rc) - release_mpi_array(cert->params, i-1); - - return rc; -} - -static int -openpgp_sig_to_gnutls_cert(gnutls_cert *cert, PKT_signature *sig) -{ - IOBUF buf = NULL; - int rc = 0; - size_t nbytes = 0; - size_t sigsize = 0; - byte *data = NULL; - PACKET pkt; - - if (!cert || !sig) - return GNUTLS_E_INVALID_PARAMETERS; - - sigsize = 20 + sig->hashed_size + sig->unhashed_size + 2*MAX_MPI_BYTES; - cdk_iobuf_new(&buf, sigsize); - memset( &pkt, 0, sizeof pkt ); - pkt.pkttype = PKT_SIGNATURE; - pkt.pkt.signature = sig; - rc = cdk_pkt_build( buf, &pkt ); - if (rc) - goto leave; - data = cdk_iobuf_getdata(buf, &nbytes); - if (data && nbytes) - { - rc = gnutls_datum_append( &cert->signature, data, nbytes); - if (rc < 0) - { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - cdk_free(data); - } - else - rc = GNUTLS_E_UNKNOWN_ERROR; - -leave: - cdk_iobuf_close(buf); - - return rc; -} - -/*- - * _gnutls_openpgp_key2gnutls_key - Converts an OpenPGP secret key to GnuTLS - * @pkey: the GnuTLS private key context to store the key. - * @raw_key: the raw data which contains the whole key packets. - * - * The RFC2440 (OpenPGP Message Format) data is converted into the - * GnuTLS specific data which is need to perform secret key operations. - -*/ -int -_gnutls_openpgp_key2gnutls_key( gnutls_private_key *pkey, - gnutls_datum raw_key ) -{ - KBNODE p = NULL, kb_sk; - PKT_secret_key *sk = NULL; - IOBUF buf; - int pke_algo, i, j, eof = 0; - size_t nbytes = 0; - int rc = 0; - - if (!pkey || raw_key.size <= 0) - return GNUTLS_E_INVALID_PARAMETERS; - - cdk_secmem_init( 16384 ); - cdk_iobuf_new(&buf, raw_key.size); - cdk_iobuf_write(buf, raw_key.data, raw_key.size); - - rc = cdk_keydb_get_keyblock( buf, &kb_sk, &eof ); - if ( !kb_sk || rc ) - { - rc = GNUTLS_E_UNKNOWN_ERROR; - goto leave; - } - p = cdk_kbnode_find( kb_sk, PKT_SECRET_KEY ); - if ( !p ) - { - rc = GNUTLS_E_NO_CERTIFICATE_FOUND; - goto leave; - } - sk = p->pkt->pkt.secret_key; - pke_algo = sk->pk->pubkey_algo; - pkey->params_size = cdk_pk_get_npkey( pke_algo ); - for (i=0; iparams_size; i++) - { - nbytes = sk->pk->mpi[i].bytes+2; - rc = _gnutls_mpi_scan_pgp(&pkey->params[i], - sk->pk->mpi[i].data, &nbytes); - if (rc) - { - rc = GNUTLS_E_MPI_SCAN_FAILED; - release_mpi_array(pkey->params, i-1); - goto leave; - } - } - pkey->params_size += cdk_pk_get_nskey( pke_algo ); - for (j=0; jmpi[j]->bytes+2; - rc = _gnutls_mpi_scan_pgp(&pkey->params[i], - sk->mpi[j]->data, &nbytes); - if (rc) - { - rc = GNUTLS_E_MPI_SCAN_FAILED; - release_mpi_array(pkey->params, i-1); - goto leave; - } - } - if ( is_ELG(pke_algo) ) - return GNUTLS_E_UNWANTED_ALGORITHM; - else if ( is_DSA(pke_algo) ) - pkey->pk_algorithm = GNUTLS_PK_DSA; - else if ( is_RSA(pke_algo) ) - pkey->pk_algorithm = GNUTLS_PK_RSA; - rc = gnutls_set_datum(&pkey->raw, raw_key.data, raw_key.size); - if (rc < 0) - { - release_mpi_array(pkey->params, i); - rc = GNUTLS_E_MEMORY_ERROR; - } - -leave: - cdk_iobuf_close(buf); - cdk_kbnode_release( kb_sk ); - - return rc; -} - -/*- - * _gnutls_openpgp_cert2gnutls_cert - Converts raw OpenPGP data to GnuTLS certs - * @cert: the certificate to store the data. - * @raw: the buffer which contains the whole OpenPGP key packets. - * - * The RFC2440 (OpenPGP Message Format) data is converted to a GnuTLS - * specific certificate. - -*/ -int -_gnutls_openpgp_cert2gnutls_cert(gnutls_cert *cert, gnutls_datum raw) -{ - KBNODE p, kb_pk = NULL; - PKT_public_key *pk = NULL; - int rc = 0; - - if (!cert) - return GNUTLS_E_INVALID_PARAMETERS; - - memset(cert, 0, sizeof *cert); - rc = datum_to_kbnode( &raw, &kb_pk ); - if ( rc ) - return rc; - p = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); - if ( !p ) - { - rc = GNUTLS_E_NO_CERTIFICATE_FOUND; - goto leave; - } - pk = p->pkt->pkt.public_key; - rc = gnutls_set_datum( &cert->raw, raw.data, raw.size ); - if (rc < 0) - { - rc = GNUTLS_E_MEMORY_ERROR; - goto leave; - } - rc = openpgp_pk_to_gnutls_cert( cert, pk ); - -leave: - cdk_kbnode_release( kb_pk ); - - return rc; -} - -/** - * gnutls_openpgp_get_key - Retrieve a key from the keyring. - * @key: the destination context to save the key. - * @keyring: the datum struct that contains all keyring information. - * @attr: The attribute (keyid, fingerprint, ...). - * @by: What attribute is used. - * - * This function can be used to retrieve keys by different pattern - * from a binary or a file keyring. - **/ -int -gnutls_openpgp_get_key(gnutls_datum *key, const gnutls_datum *keyring, - key_attr_t by, opaque *pattern) -{ - int rc = 0; - keybox_blob *blob = NULL; - KEYDB_HD khd = NULL; - KBNODE pk = NULL; - KEYDB_SEARCH ks; - - if (!key || !keyring || by == KEY_ATTR_NONE) - return GNUTLS_E_INVALID_PARAMETERS; - - blob = kbx_read_blob( keyring, 0 ); - if (!blob) - return GNUTLS_E_MEMORY_ERROR; - khd = kbx_to_keydb( blob ); - ks.type = by; - switch (by) - { - case KEY_ATTR_SHORT_KEYID: - ks.u.keyid[1] = buffer_to_u32(pattern); - break; - - case KEY_ATTR_KEYID: - ks.u.keyid[0] = buffer_to_u32(pattern); - ks.u.keyid[1] = buffer_to_u32(pattern+4); - break; - - case KEY_ATTR_FPR: - memcpy(ks.u.fpr, pattern, 20); - break; - - default: - goto leave; - } - - rc = cdk_keydb_search( khd, &ks, &pk ); - if (rc) - { - rc = GNUTLS_E_NO_CERTIFICATE_FOUND; - goto leave; - } - - if ( !cdk_kbnode_find( pk, PKT_PUBLIC_KEY ) ) - { - rc = GNUTLS_E_NO_CERTIFICATE_FOUND; - goto leave; - } - - rc = kbnode_to_datum( pk, key ); - -leave: - cdk_free( khd ); - cdk_kbnode_release( pk ); - kbx_blob_release( blob ); - - return rc; -} - -int -gnutls_certificate_set_openpgp_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, - gnutls_datum *cert, - gnutls_datum *key) -{ - gnutls_datum raw; - KBNODE kb_pk = NULL, pkt; - int rc = 0; - int i; - - if (!res || !key || !cert) - return GNUTLS_E_INVALID_PARAMETERS; - - rc = datum_to_kbnode( cert, &kb_pk ); - if (rc) - goto leave; - - /* fixme: too much duplicated code from (set_openpgp_key_file) */ - res->cert_list = gnutls_realloc(res->cert_list, - (1+res->ncerts)*sizeof(gnutls_cert*)); - if (res->cert_list == NULL) - { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - res->cert_list_length = gnutls_realloc(res->cert_list_length, - (1+res->ncerts)*sizeof(int)); - if (res->cert_list_length == NULL) - { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - res->cert_list[res->ncerts] = gnutls_calloc(1, sizeof(gnutls_cert)); - if (res->cert_list[res->ncerts] == NULL) - { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - for (i=1, pkt=kb_pk; pkt && pkt->pkt->pkttype; pkt=pkt->next) - { - if (i > MAX_PARAMS_SIZE) - break; - if (pkt->pkt->pkttype == PKT_PUBLIC_KEY) - { - int n = res->ncerts; - PKT_public_key *pk = pkt->pkt->pkt.public_key; - res->cert_list_length[n] = 1; - gnutls_set_datum(&res->cert_list[n][0].raw, cert->data, cert->size); - openpgp_pk_to_gnutls_cert( &res->cert_list[n][0], pk ); - i++; - } - else if (pkt->pkt->pkttype == PKT_SIGNATURE) - { - int n = res->ncerts; - PKT_signature *sig = pkt->pkt->pkt.signature; - openpgp_sig_to_gnutls_cert( &res->cert_list[n][0], sig ); - } - } - - res->ncerts++; - res->pkey = gnutls_realloc(res->pkey, - (res->ncerts)*sizeof(gnutls_private_key)); - if (res->pkey == NULL) - { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - /* ncerts has been incremented before */ - gnutls_set_datum(&raw, key->data, key->size); - rc =_gnutls_openpgp_key2gnutls_key( &res->pkey[res->ncerts-1], raw); - gnutls_free_datum(&raw); - -leave: - cdk_kbnode_release( kb_pk ); - - return rc; -} - -/** - * gnutls_certificate_set_openpgp_key_file - Used to set OpenPGP keys - * @res: the destination context to save the data. - * @CERTFILE: the file that contains the public key. - * @KEYFILE: the file that contains the secret key. - * - * This funtion is used to load OpenPGP keys into the GnuTLS structure. - * It doesn't matter whether the keys are armored or but, but the files - * should only contain one key which should not be encrypted. - **/ -int -gnutls_certificate_set_openpgp_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res, - char* CERTFILE, - char* KEYFILE) -{ - IOBUF inp = NULL; - KBNODE kb_pk = NULL, pkt; - armor_filter_s afx; - gnutls_datum raw; - int eof = 0, i = 0; - int rc = 0; - - if (!res || !KEYFILE || !CERTFILE) - return GNUTLS_E_INVALID_PARAMETERS; - - if ( !file_exist(CERTFILE) || !file_exist(KEYFILE) ) - return GNUTLS_E_FILE_ERROR; - - rc = cdk_iobuf_open(&inp, CERTFILE, IOBUF_MODE_RD); - if ( rc ) - return GNUTLS_E_FILE_ERROR; - if ( cdk_armor_filter_use( inp ) ) - { - memset( &afx, 0, sizeof afx ); - rc = cdk_iobuf_push_filter( inp, &afx, cdk_armor_filter ); - if ( rc ) - { - cdk_iobuf_close( inp ); - rc = GNUTLS_E_ASCII_ARMOR_ERROR; - goto leave; - } - /*cdk_iobuf_close( inp );*/ - } - - res->cert_list = gnutls_realloc(res->cert_list, - (1+res->ncerts)*sizeof(gnutls_cert*)); - if (res->cert_list == NULL) - { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - res->cert_list_length = gnutls_realloc(res->cert_list_length, - (1+res->ncerts)*sizeof(int)); - if (res->cert_list_length == NULL) - { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - res->cert_list[res->ncerts] = gnutls_calloc(1, sizeof(gnutls_cert)); - if (res->cert_list[res->ncerts] == NULL) - { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - do { - rc = cdk_keydb_get_keyblock( inp, &kb_pk, &eof ); - if ( !kb_pk || rc ) - break; - for (i=1, pkt=kb_pk; pkt && pkt->pkt->pkttype; pkt=pkt->next) - { - if (i > MAX_PARAMS_SIZE) - break; - if (pkt->pkt->pkttype == PKT_PUBLIC_KEY) - { - int n = res->ncerts; - PKT_public_key *pk = pkt->pkt->pkt.public_key; - res->cert_list_length[n] = 1; - iobuf_to_datum(inp, &res->cert_list[n][0].raw); - openpgp_pk_to_gnutls_cert( &res->cert_list[n][0], pk ); - i++; - } - else if (pkt->pkt->pkttype == PKT_SIGNATURE) - { - int n = res->ncerts; - PKT_signature *sig = pkt->pkt->pkt.signature; - openpgp_sig_to_gnutls_cert( &res->cert_list[n][0], sig ); - } - } - } while (!eof && !rc); - - cdk_iobuf_close(inp); - if ( rc ) - { - cdk_kbnode_release( kb_pk ); - rc = GNUTLS_E_UNKNOWN_ERROR; - goto leave; - } - cdk_kbnode_release( kb_pk ); - - rc = cdk_iobuf_open( &inp, KEYFILE, IOBUF_MODE_RD ); - if ( rc ) - return GNUTLS_E_FILE_ERROR; - if ( cdk_armor_filter_use( inp ) ) - { - memset( &afx, 0, sizeof afx ); - rc = cdk_iobuf_push_filter( inp, &afx, cdk_armor_filter ); - if ( rc ) - { - cdk_iobuf_close( inp ); - rc = GNUTLS_E_ASCII_ARMOR_ERROR; - goto leave; - } - /*cdk_iobuf_close( inp );*/ - } - - iobuf_to_datum( inp, &raw ); - cdk_iobuf_close( inp ); - - res->pkey = gnutls_realloc(res->pkey, - (res->ncerts+1)*sizeof(gnutls_private_key)); - if (res->pkey == NULL) - { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - res->ncerts++; - - /* ncerts has been incremented before */ - rc =_gnutls_openpgp_key2gnutls_key( &res->pkey[res->ncerts-1], raw); - -leave: - - return rc; -} - -int -gnutls_openpgp_count_key_names( const gnutls_datum *cert ) -{ - KBNODE kb_pk = NULL, pkt; - int nuids = 0; - - if ( !cert ) - return 0; - - if ( datum_to_kbnode( cert, &kb_pk ) ) - return 0; - for ( pkt=kb_pk; pkt; pkt=pkt->next ) - { - if ( pkt->pkt->pkttype == PKT_USER_ID ) - nuids++; - } - return nuids; -} /* gnutls_openpgp_count_key_names */ - -/** - * gnutls_openpgp_extract_key_name - Extracts the userID - * @cert: the raw data that contains the OpenPGP public key. - * @dn: the structure to store the userID specific data in. - * - * Extracts the userID from the raw OpenPGP key. - **/ -int -gnutls_openpgp_extract_key_name( const gnutls_datum *cert, - int idx, - gnutls_openpgp_name *dn ) -{ - KBNODE kb_pk = NULL, pkt; - PKT_user_id *uid = NULL; - char *email; - int rc = 0; - int pos1 = 0, pos2 = 0; - size_t size = 0; - int pos = 0; - - if (!cert || !dn) - return GNUTLS_E_INVALID_PARAMETERS; - - if ( idx < 0 || idx > gnutls_openpgp_count_key_names( cert ) ) - return GNUTLS_E_UNKNOWN_ERROR; - - memset(dn, 0, sizeof *dn); - rc = datum_to_kbnode( cert, &kb_pk ); - if ( rc ) - return rc; - if ( !idx ) - pkt = cdk_kbnode_find( kb_pk, PKT_USER_ID ); - else - { - for ( pos=0, pkt=kb_pk; pkt; pkt=pkt->next ) - { - if ( pkt->pkt->pkttype == PKT_USER_ID && ++pos == idx ) - break; - } - } - if ( pkt ) - uid = pkt->pkt->pkt.user_id; - if ( !uid ) - { - rc = GNUTLS_E_UNKNOWN_ERROR; - goto leave; - } - size = uid->len < OPENPGP_NAME_SIZE? uid->len : OPENPGP_NAME_SIZE-1; - memcpy(dn->name, uid->name, size); - dn->name[size] = '\0'; /* make sure it's a string */ - - /* Extract the email address from the userID string and save - it to the email field. */ - email = strchr(uid->name, '<'); - if ( email ) - pos1 = email-uid->name+1; - email = strchr(uid->name, '>'); - if ( email ) - pos2 = email-uid->name+1; - if (pos1 && pos2) - { - pos2 -= pos1; - size = pos2 < OPENPGP_NAME_SIZE? pos2 : OPENPGP_NAME_SIZE-1; - memcpy(dn->email, uid->name+pos1, size); - dn->email[size-1] = '\0'; /* make sure it's a string */ - } - if ( uid->is_revoked ) - { - rc = GNUTLS_E_OPENPGP_UID_REVOKED; - goto leave; - } - -leave: - cdk_kbnode_release( kb_pk ); - - return rc; -} - -/** - * gnutls_openpgp_extract_key_pk_algorithm - This function returns the key's PublicKey algorithm - * @cert: is an OpenPGP key - * @bits: if bits is non null it will hold the size of the parameters' in bits - * - * This function will return the public key algorithm of an OpenPGP - * certificate. - * - * If bits is non null, it should have enough size to hold the parameters - * size in bits. For RSA the bits returned is the modulus. - * For DSA the bits returned are of the public exponent. - * - * Returns a member of the GNUTLS_PKAlgorithm enumeration on success, - * or a negative value on error. - * - **/ -int -gnutls_openpgp_extract_key_pk_algorithm(const gnutls_datum *cert, int *r_bits) -{ - KBNODE kb_pk = NULL, pkt; - int algo = 0; - - if ( !cert ) - return GNUTLS_E_INVALID_PARAMETERS; - - if ( datum_to_kbnode( cert, &kb_pk ) ) - return 0; - pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); - if ( pkt && r_bits) - *r_bits = cdk_pk_get_nbits( pkt->pkt->pkt.public_key ); - algo = pkt->pkt->pkt.public_key->pubkey_algo; - if ( is_RSA( algo ) ) - algo = GNUTLS_PK_RSA; - else if ( is_DSA( algo ) ) - algo = GNUTLS_PK_DSA; - else - algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM; - cdk_kbnode_release( kb_pk ); - - return algo; -} - - -/** - * gnutls_openpgp_extract_key_version - Extracts the version of the key. - * @cert: the raw data that contains the OpenPGP public key. - * - * Extract the version of the OpenPGP key. - **/ -int -gnutls_openpgp_extract_key_version( const gnutls_datum *cert ) -{ - KBNODE kb_pk = NULL, pkt; - int version = 0; - - if (!cert) - return GNUTLS_E_INVALID_PARAMETERS; - - if ( datum_to_kbnode( cert, &kb_pk ) ) - return 0; - pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); - if ( pkt ) - version = pkt->pkt->pkt.public_key->version; - cdk_kbnode_release( kb_pk ); - - return version; -} - -/** - * gnutls_openpgp_extract_key_creation_time - Extract the timestamp - * @cert: the raw data that contains the OpenPGP public key. - * - * Returns the timestamp when the OpenPGP key was created. - **/ -time_t -gnutls_openpgp_extract_key_creation_time( const gnutls_datum *cert ) -{ - KBNODE kb_pk = NULL, pkt; - time_t timestamp = 0; - - if (!cert) - return GNUTLS_E_INVALID_PARAMETERS; - - if ( datum_to_kbnode( cert, &kb_pk ) ) - return 0; - pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); - if ( pkt ) - timestamp = pkt->pkt->pkt.public_key->timestamp; - cdk_kbnode_release( kb_pk ); - - return timestamp; -} - -/** - * gnutls_openpgp_extract_key_expiration_time - Extract the expire date - * @cert: the raw data that contains the OpenPGP public key. - * - * Returns the time when the OpenPGP key expires. A value of '0' means - * that the key doesn't expire at all. - **/ -time_t -gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert ) -{ - KBNODE kb_pk = NULL, pkt; - time_t expiredate = 0; - - if (!cert) - return GNUTLS_E_INVALID_PARAMETERS; - - if ( datum_to_kbnode( cert, &kb_pk ) ) - return 0; - pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); - if ( pkt ) - expiredate = pkt->pkt->pkt.public_key->expiredate; - cdk_kbnode_release( kb_pk ); - - return expiredate; -} - -int -_gnutls_openpgp_get_key_trust(const char *trustdb, - const gnutls_datum *key, - int *r_success) -{ - int flags = 0; - int ot = 0, trustval = 0; - int rc = 0; - KBNODE kb_pk = NULL, pkt; - PKT_public_key *pk = NULL; - IOBUF buf; - - if (!trustdb || !key || !r_success) - return GNUTLS_E_NO_CERTIFICATE_FOUND; - - *r_success = 0; - rc = datum_to_kbnode( key, &kb_pk ); - if ( rc ) - return GNUTLS_E_NO_CERTIFICATE_FOUND; - - pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); - if ( pkt ) - pk = pkt->pkt->pkt.public_key; - if ( !pk ) - return GNUTLS_E_NO_CERTIFICATE_FOUND; - - rc = cdk_iobuf_open( &buf, trustdb, IOBUF_MODE_RD ); - if ( rc ) - { - trustval = GNUTLS_E_NO_CERTIFICATE_FOUND; - goto leave; - } - rc = cdk_trustdb_get_ownertrust( buf, pk, &ot, &flags ); - cdk_iobuf_close( buf ); - if ( rc ) /* no ownertrust record was found */ - { - trustval = 0; - *r_success = 1; - goto leave; - } - - if (flags & TRUST_FLAG_DISABLED) - { - trustval |= GNUTLS_CERT_NOT_TRUSTED; - trustval |= GNUTLS_CERT_INVALID; - goto leave; - } - if (flags & TRUST_FLAG_REVOKED) - { - trustval |= GNUTLS_CERT_NOT_TRUSTED; - trustval |= GNUTLS_CERT_REVOKED; - } - switch (ot) - { - case TRUST_NEVER: - trustval |= GNUTLS_CERT_NOT_TRUSTED; - break; - - case TRUST_UNKNOWN: - case TRUST_UNDEFINED: - case TRUST_MARGINAL: - - case TRUST_FULLY: - case TRUST_ULTIMATE: - trustval |= 1; /* means okay */ - *r_success = 1; - break; - } - -leave: - cdk_kbnode_release( kb_pk ); - return trustval; -} - -/** - * gnutls_openpgp_verify_key - Verify all signatures on the key - * @cert_list: the structure that holds the certificates. - * @cert_list_lenght: the items in the cert_list. - * - * Verify all signatures in the certificate list. When the key - * is not available, the signature is skipped. - * The return value is one of the CertificateStatus entries. - **/ -int -gnutls_openpgp_verify_key( const char *trustdb, - const gnutls_datum* keyring, - const gnutls_datum* cert_list, - int cert_list_length ) -{ - KBNODE kb_pk = NULL; - KEYDB_HD khd = NULL; - keybox_blob *blob = NULL; - int rc = 0; - int status = 0; - - if (!cert_list || !cert_list_length || !keyring) - return GNUTLS_E_NO_CERTIFICATE_FOUND; - - if (cert_list_length != 1 || !keyring->size) - return GNUTLS_E_NO_CERTIFICATE_FOUND; - - blob = kbx_read_blob(keyring, 0); - if (!blob) - return GNUTLS_CERT_INVALID|GNUTLS_CERT_NOT_TRUSTED; - khd = kbx_to_keydb(blob); - if (!khd) - { - rc = GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED; - goto leave; - } - - if ( trustdb ) - { - int success = 0; - rc = _gnutls_openpgp_get_key_trust(trustdb, cert_list, &success); - if (!success) - goto leave; - } - - rc = datum_to_kbnode( cert_list, &kb_pk ); - if (rc) - { - goto leave; - return GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED; - } - - rc = cdk_key_check_sigs( kb_pk, khd, &status ); - if (rc == CDKERR_NOKEY) - rc = 0; /* fixme */ - - switch (status) - { - case CDK_KEY_INVALID: - rc = GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED; - break; - - case CDK_KEY_REVOKED: - rc = GNUTLS_CERT_REVOKED | GNUTLS_CERT_NOT_TRUSTED; - break; - - } - -leave: - kbx_blob_release( blob ); - cdk_free( khd ); - cdk_kbnode_release( kb_pk ); - - return rc; -} - -/** - * gnutls_openpgp_fingerprint - Gets the fingerprint - * @cert: the raw data that contains the OpenPGP public key. - * @fpr: the buffer to save the fingerprint. - * @fprlen: the integer to save the length of the fingerprint. - * - * Returns the fingerprint of the OpenPGP key. Depence on the algorithm, - * the fingerprint can be 16 or 20 bytes. - **/ -int -gnutls_openpgp_fingerprint(const gnutls_datum *cert, byte *fpr, size_t *fprlen) -{ - KBNODE kb_pk = NULL, pkt; - PKT_public_key *pk = NULL; - int rc = 0; - - if (!cert || !fpr || !fprlen) - return GNUTLS_E_UNKNOWN_ERROR; - - *fprlen = 0; - rc = datum_to_kbnode( cert, &kb_pk ); - if (rc) - return rc; - pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); - if ( pkt ) - pk = pkt->pkt->pkt.public_key; - if ( !pk ) - return GNUTLS_E_UNKNOWN_ERROR; - - *fprlen = 20; - if ( is_RSA(pk->pubkey_algo) && pk->version < 4 ) - *fprlen = 16; - cdk_pk_get_fingerprint( pk, fpr ); - - return 0; -} - -/** - * gnutls_openpgp_keyid - Gets the keyID - * @cert: the raw data that contains the OpenPGP public key. - * @keyid: the buffer to save the keyid. - * - * Returns the 64-bit keyID of the OpenPGP key. - **/ -int -gnutls_openpgp_keyid( const gnutls_datum *cert, uint32 *keyid ) -{ - KBNODE kb_pk = NULL, pkt; - PKT_public_key *pk = NULL; - int rc = 0; - - if (!cert || !keyid) - return GNUTLS_E_UNKNOWN_ERROR; - - rc = datum_to_kbnode( cert, &kb_pk ); - if (rc) - return rc; - - pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); - if ( pkt ) - pk = pkt->pkt->pkt.public_key; - if ( !pk ) - return GNUTLS_E_UNKNOWN_ERROR; - cdk_pk_get_keyid( pk, (u32 *)keyid ); - - return 0; -} - -/** - * gnutls_openpgp_add_keyring_file - Adds a keyring file for OpenPGP - * @keyring: data buffer to store the file. - * @name: filename of the keyring. - * - * The function is used to set keyrings that will be used internally - * by various OpenCDK functions. For example to find a key when it - * is needed for an operations. - **/ -int -gnutls_openpgp_add_keyring_file(gnutls_datum *keyring, const char *name) -{ - byte *blob; - size_t nbytes; - IOBUF inp = NULL; - int enc = 0; - int rc = 0; - - if (!keyring || !name) - return GNUTLS_E_INVALID_PARAMETERS; - - rc = cdk_iobuf_open( &inp, name, IOBUF_MODE_RD ); - if ( rc ) - return GNUTLS_E_FILE_ERROR; - enc = cdk_armor_filter_use( inp ); - cdk_iobuf_close( inp ); - - blob = kbx_data_to_keyring( KBX_BLOB_FILE, enc, name, strlen(name), &nbytes); - if (blob && nbytes) - { - if ( gnutls_datum_append( keyring, blob, nbytes ) < 0 ) - { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - gnutls_free(blob); - } - - return 0; -} - -/** - * gnutls_openpgp_add_keyring_mem - Adds keyring data for OpenPGP - * @keyring: data buffer to store the file. - * @data: the binary data of the keyring. - * @len: the size of the binary buffer. - * - * Same as gnutls_openpgp_add_keyring_mem but now we store the - * data instead of the filename. - **/ -int -gnutls_openpgp_add_keyring_mem(gnutls_datum *keyring, - const char *data, size_t len) -{ - byte *blob; - size_t nbytes = 0; - - if (!keyring || !data || !len) - return GNUTLS_E_INVALID_PARAMETERS; - - blob = kbx_data_to_keyring( KBX_BLOB_DATA, 0, data, len, &nbytes ); - if ( blob && nbytes ) - { - if ( gnutls_datum_append( keyring, blob, nbytes ) < 0 ) - { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - gnutls_free(blob); - } - - return 0; -} - -int -gnutls_certificate_set_openpgp_keyring_file(GNUTLS_CERTIFICATE_CREDENTIALS c, - const char *file) -{ - if (!c || !file) - return GNUTLS_E_INVALID_PARAMETERS; - - if ( !file_exist(file) ) - return GNUTLS_E_FILE_ERROR; - - return gnutls_openpgp_add_keyring_file(&c->keyring, file); -} - -int -gnutls_certificate_set_openpgp_keyring_mem(GNUTLS_CERTIFICATE_CREDENTIALS c, - const char *file) -{ - IOBUF inp = NULL; - byte *data = NULL; - size_t nbytes = 0; - armor_filter_s afx; - int rc = 0; - - if (!c || !file) - return GNUTLS_E_INVALID_PARAMETERS; - - if ( !file_exist(file) ) - return GNUTLS_E_FILE_ERROR; - - rc = cdk_iobuf_open(&inp, file, IOBUF_MODE_RD); - if ( rc ) - return GNUTLS_E_FILE_ERROR; - if ( cdk_armor_filter_use( inp ) ) - { - memset( &afx, 0, sizeof afx ); - rc = cdk_iobuf_push_filter( inp, &afx, cdk_armor_filter ); - if ( rc ) - { - cdk_iobuf_close( inp ); - return GNUTLS_E_ASCII_ARMOR_ERROR; - } - } - - data = cdk_iobuf_getdata( inp, &nbytes ); - if (data && nbytes) - { - rc = gnutls_openpgp_add_keyring_mem( &c->keyring, data, nbytes ); - cdk_free(data); - } - else - rc = GNUTLS_E_UNKNOWN_ERROR; - cdk_iobuf_close(inp); - - return rc; -} - -/** - * gnutls_openpgp_recv_key - Receives a key from a HKP keyserver. - * @host - the hostname of the keyserver. - * @port - the service port (if not set use 11371). - * @keyid - The 32-bit keyID (rightmost bits keyid[1]) - * @key - Context to store the raw (dearmored) key. - * - * Try to connect to a public keyserver to get the specified key. - **/ -int -gnutls_openpgp_recv_key(const char *host, short port, uint32 keyid, - gnutls_datum *key) -{ - int rc = 0, state = 0; - struct hostent *hp; - struct sockaddr_in sock; - armor_filter_s afx; - char *request = NULL; - char buffer[4096]; - IOBUF buf = NULL; - int fd = -1; - byte *data; - ssize_t n = 0, nbytes = 0; - - if (!host || !key) - return GNUTLS_E_INVALID_PARAMETERS; - - if (!port) - port = 11371; /* standard service port */ - - hp = gethostbyname(host); - if (hp == NULL) - return -1; - - memset(&sock, 0, sizeof sock); - memcpy(&sock.sin_addr, hp->h_addr, hp->h_length); - sock.sin_family = hp->h_addrtype; - sock.sin_port = htons(port); - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd == -1) - return -1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)1, 1); - if ( connect(fd, (struct sockaddr*)&sock, sizeof(sock)) == -1 ) - { - close(fd); - return -1; - } - - request = cdk_alloc_clear(strlen(host)+100); - if ( request == NULL ) - { - close( fd ); - return -1; - } - sprintf(request, "GET /pks/lookup?op=get&search=0x%08X HTTP/1.0\r\n" - "Host: %s:%d\r\n", (u32)keyid, host, port); - if ( write(fd, request, strlen(request)) == -1 ) - { - cdk_free(request); - close(fd); - return -1; - } - cdk_free(request); - - buf = cdk_iobuf_temp(); - while ( (n = read(fd, buffer, sizeof(buffer)-1)) > 0 ) - { - buffer[n] = '\0'; - nbytes += n; - if ( nbytes > cdk_iobuf_getsize( buf ) ) - cdk_iobuf_expand(buf, n); - cdk_iobuf_write(buf, buffer, n); - if ( strstr(buffer, "
") || strstr(buffer, "
") ) - state++; - } - - if (state != 2) - { - rc = GNUTLS_E_UNKNOWN_ERROR; - goto leave; - } - memset(&afx, 0, sizeof afx); - rc = cdk_iobuf_push_filter(buf, &afx, cdk_armor_filter); - if (rc) - { - rc = GNUTLS_E_ASCII_ARMOR_ERROR; - goto leave; - } - data = cdk_iobuf_getdata(buf, &n); - if (data && n) - { - gnutls_set_datum(key, data, n); - cdk_free(data); - } - -leave: - cdk_iobuf_close(buf); - close(fd); - - return 0; -} - -/*- - * _gnutls_openpgp_request_key - Receives a key from a database, key server etc - * @ret - a pointer to gnutls_datum structure. - * @cred - a GNUTLS_CERTIFICATE_CREDENTIALS structure. - * @key_fingerprint - The keyFingerprint - * @key_fingerprint_size - the size of the fingerprint - * - * Retrieves a key from a local database, keyring, or a key server. The - * return value is locally allocated. - * - -*/ -int -_gnutls_openpgp_request_key( gnutls_datum* ret, - const GNUTLS_CERTIFICATE_CREDENTIALS cred, - opaque* key_fpr, - int key_fpr_size) -{ - int rc = 0; - uint32 keyid; - - if (!ret || !cred || !key_fpr) - return GNUTLS_E_INVALID_PARAMETERS; - - if (key_fpr_size != 16 && key_fpr_size != 20) - return GNUTLS_E_HASH_FAILED; /* only MD5 and SHA1 are supported */ - - rc = gnutls_openpgp_get_key(ret, &cred->keyring, KEY_ATTR_FPR, key_fpr); - if (rc >= 0) - goto leave; - - keyid = buffer_to_u32(key_fpr+16); - rc = gnutls_openpgp_recv_key(cred->pgp_key_server, - cred->pgp_key_server_port, - keyid, ret); - -leave: - return rc; -} - -/** - * gnutls_certificate_set_openpgp_keyserver - Used to set an OpenPGP key server - * @res: the destination context to save the data. - * @server: is the key server address - * @port: is the key server port to connect to - * - * This funtion will set a key server for use with openpgp keys. This - * key server will only be used if the peer sends a key fingerprint instead - * of a key in the handshake. Using a key server may delay the handshake - * process. - * - **/ -void -gnutls_certificate_set_openpgp_keyserver(GNUTLS_CERTIFICATE_CREDENTIALS res, - char* keyserver, - int port) -{ - if (!res || !keyserver) - return; - - if (!port) - port = 11371; - - res->pgp_key_server = gnutls_strdup( keyserver ); - res->pgp_key_server_port = port; -} - -void -gnutls_certificate_set_openpgp_trustdb(GNUTLS_CERTIFICATE_CREDENTIALS res, - char* trustdb) -{ - if (!res || !trustdb) - return; - - res->pgp_trustdb = gnutls_strdup(trustdb); -} - -#else /*!HAVE_LIBOPENCDK*/ - -int -_gnutls_openpgp_key2gnutls_key(gnutls_private_key *pkey, - gnutls_datum raw_key) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int -_gnutls_openpgp_cert2gnutls_cert(gnutls_cert *cert, gnutls_datum raw) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int -gnutls_certificate_set_openpgp_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, - gnutls_datum *cert, - gnutls_datum *key) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int -gnutls_certificate_set_openpgp_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res, - char* CERTFILE, - char* KEYFILE) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int -gnutls_openpgp_extract_key_name( const gnutls_datum *cert, int idx, - gnutls_openpgp_name *dn ) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int -gnutls_openpgp_extract_key_pk_algorithm(const gnutls_datum *cert, int *r_bits) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int -gnutls_openpgp_extract_key_version( const gnutls_datum *cert ) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -time_t -gnutls_openpgp_extract_key_creation_time( const gnutls_datum *cert ) -{ - return (time_t)-1; -} - -time_t -gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert ) -{ - return (time_t)-1; -} - -int -gnutls_openpgp_verify_key(const char* ign, const gnutls_datum* keyring, - const gnutls_datum* cert_list, - int cert_list_length) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int -gnutls_openpgp_fingerprint(const gnutls_datum *cert, byte *fpr, size_t *fprlen) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int -gnutls_openpgp_add_keyring_file(gnutls_datum *keyring, const char *name) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int -gnutls_openpgp_add_keyring_mem(gnutls_datum *keyring, - const char *data, size_t len) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int -gnutls_certificate_set_openpgp_keyring_file(GNUTLS_CERTIFICATE_CREDENTIALS c, - const char *file) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int -gnutls_certificate_set_openpgp_keyring_mem(GNUTLS_CERTIFICATE_CREDENTIALS c, - const char *file) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int -_gnutls_openpgp_request_key( gnutls_datum* ret, - const GNUTLS_CERTIFICATE_CREDENTIALS cred, - opaque* key_fpr, - int key_fpr_size) -{ - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -void -gnutls_certificate_set_openpgp_keyserver(GNUTLS_CERTIFICATE_CREDENTIALS res, - char* keyserver, - int port) -{ - return; -} - -void -gnutls_certificate_set_openpgp_trustdb(GNUTLS_CERTIFICATE_CREDENTIALS res, - char* trustdb) -{ - return; -} - -#endif /* HAVE_LIBOPENCDK */ - - - - - - diff --git a/lib/gnutls_openpgp.h b/lib/gnutls_openpgp.h deleted file mode 100644 index a0ec4dd2e1..0000000000 --- a/lib/gnutls_openpgp.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef GNUTLS_OPENPGP_H -#define GNUTLS_OPENPGP_H - -#include - -/* OpenCDK compatible */ -typedef enum { - KEY_ATTR_NONE = 0, - KEY_ATTR_SHORT_KEYID = 3, - KEY_ATTR_KEYID = 4, - KEY_ATTR_FPR = 5 -} key_attr_t; - -int gnutls_certificate_set_openpgp_key_file( - GNUTLS_CERTIFICATE_CREDENTIALS res, - char* CERTFILE, - char* KEYFILE); - -int gnutls_openpgp_count_key_names( const gnutls_datum *cert ); - -int gnutls_openpgp_extract_key_name( const gnutls_datum *cert, - int idx, - gnutls_openpgp_name *dn ); - -int gnutls_openpgp_extract_key_pk_algorithm(const gnutls_datum *cert, - int *r_bits); - -int gnutls_openpgp_extract_key_version( const gnutls_datum *cert ); - -time_t gnutls_openpgp_extract_key_creation_time( const gnutls_datum *cert ); - -time_t gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert ); - -int gnutls_openpgp_verify_key( const char *trustdb, - const gnutls_datum *keyring, - const gnutls_datum* cert_list, - int cert_list_length ); - -int gnutls_openpgp_fingerprint( const gnutls_datum *cert, opaque *fpr, - size_t *fprlen ); - -int gnutls_openpgp_keyid( const gnutls_datum *cert, uint32 *keyid ); - -int gnutls_openpgp_add_keyring_mem(gnutls_datum *keyring, - const char *data, size_t len); - -int gnutls_openpgp_add_keyring_file(gnutls_datum *keyring, const char *name); - -int gnutls_certificate_set_openpgp_keyring_file( - GNUTLS_CERTIFICATE_CREDENTIALS c, - const char *file); -int gnutls_certificate_set_openpgp_keyring_mem( - GNUTLS_CERTIFICATE_CREDENTIALS c, - const char *file); - -int gnutls_openpgp_get_key(gnutls_datum *key, const gnutls_datum *keyring, - key_attr_t by, opaque *pattern); - -int gnutls_openpgp_get_key_trust(const char *trustdb, gnutls_datum *key); - - -int gnutls_openpgp_recv_key(const char *host, short port, uint32 keyid, - gnutls_datum *key); - -/* internal */ -int _gnutls_openpgp_cert2gnutls_cert(gnutls_cert *cert, gnutls_datum raw); - -int -_gnutls_openpgp_request_key( gnutls_datum* ret, - const GNUTLS_CERTIFICATE_CREDENTIALS cred, opaque* key_fpr, - int key_fpr_size); - -#endif /*GNUTLS_OPENPGP_H*/ diff --git a/lib/gnutls_srp.c b/lib/gnutls_srp.c deleted file mode 100644 index e4eb030ba3..0000000000 --- a/lib/gnutls_srp.c +++ /dev/null @@ -1,568 +0,0 @@ -/* - * Copyright (C) 2001 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * GNUTLS 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 2 of the License, or - * (at your option) any later version. - * - * GNUTLS 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include - -#ifdef ENABLE_SRP - -#include -#include -#include -#include -#include "debug.h" - - -/* Here functions for SRP (like g^x mod n) are defined - */ - - -int _gnutls_srp_gx(opaque * text, int textsize, opaque ** result, GNUTLS_MPI g, - GNUTLS_MPI prime) -{ - - GNUTLS_MPI x, e; - int result_size; - - if (_gnutls_mpi_scan(&x, text, &textsize)) { - gnutls_assert(); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - e = _gnutls_mpi_alloc_like(prime); - if (e==NULL) { - gnutls_assert(); - _gnutls_mpi_release(&x); - return GNUTLS_E_MEMORY_ERROR; - } - - /* e = g^x mod prime (n) */ - _gnutls_mpi_powm(e, g, x, prime); - _gnutls_mpi_release(&x); - - _gnutls_mpi_print( NULL, &result_size, e); - if (result != NULL) { - *result = gnutls_malloc(result_size); - if ((*result)==NULL) return GNUTLS_E_MEMORY_ERROR; - - _gnutls_mpi_print( *result, &result_size, e); - } - - _gnutls_mpi_release(&e); - - return result_size; - -} - - -/**************** - * Choose a random value b and calculate B = (v + g^b) % N. - * Return: B and if ret_b is not NULL b. - */ -GNUTLS_MPI _gnutls_calc_srp_B(GNUTLS_MPI * ret_b, GNUTLS_MPI g, GNUTLS_MPI n, GNUTLS_MPI v) -{ - GNUTLS_MPI tmpB; - GNUTLS_MPI b, B; - int bits; - - /* calculate: B = (v + g^b) % N */ - bits = _gnutls_mpi_get_nbits(n); - b = _gnutls_mpi_new(bits); /* FIXME: allocate in secure memory */ - if (b==NULL) { - gnutls_assert(); - return NULL; - } - - _gnutls_mpi_randomize(b, bits, GCRY_STRONG_RANDOM); - - tmpB = _gnutls_mpi_new(bits); /* FIXME: allocate in secure memory */ - if (tmpB==NULL) { - gnutls_assert(); - _gnutls_mpi_release( &b); - return NULL; - } - - B = _gnutls_mpi_new(bits); /* FIXME: allocate in secure memory */ - if (tmpB==NULL) { - gnutls_assert(); - _gnutls_mpi_release( &b); - _gnutls_mpi_release( &tmpB); - return NULL; - } - - _gnutls_mpi_powm(tmpB, g, b, n); - _gnutls_mpi_addm(B, v, tmpB, n); - - _gnutls_mpi_release(&tmpB); - - if (ret_b) - *ret_b = b; - else - _gnutls_mpi_release(&b); - - return B; -} - -GNUTLS_MPI _gnutls_calc_srp_u(GNUTLS_MPI B) -{ - int b_size; - opaque *b_holder, hd[MAX_HASH_SIZE]; - GNUTLS_HASH_HANDLE td; - uint32 u; - GNUTLS_MPI ret; - - _gnutls_mpi_print( NULL, &b_size, B); - b_holder = gnutls_malloc(b_size); - if (b_holder==NULL) return NULL; - - _gnutls_mpi_print( b_holder, &b_size, B); - - - td = _gnutls_hash_init(GNUTLS_MAC_SHA); - if (td==NULL) { - gnutls_free(b_holder); - gnutls_assert(); - return NULL; - } - _gnutls_hash(td, b_holder, b_size); - _gnutls_hash_deinit(td, hd); - - memcpy(&u, hd, sizeof(u)); - - gnutls_free(b_holder); - - ret = _gnutls_mpi_set_ui(NULL, u); - if (ret==NULL) { - gnutls_assert(); - return NULL; - } - - return ret; -} - -/* S = (A * v^u) ^ b % N - * this is our shared key - */ -GNUTLS_MPI _gnutls_calc_srp_S1(GNUTLS_MPI A, GNUTLS_MPI b, GNUTLS_MPI u, GNUTLS_MPI v, GNUTLS_MPI n) -{ - GNUTLS_MPI tmp1, tmp2; - GNUTLS_MPI S; - - S = _gnutls_mpi_alloc_like(n); - if (S==NULL) - return NULL; - - tmp1 = _gnutls_mpi_alloc_like(n); - tmp2 = _gnutls_mpi_alloc_like(n); - - if (tmp1 == NULL || tmp2 == NULL) { - _gnutls_mpi_release(&tmp1); - _gnutls_mpi_release(&tmp2); - return NULL; - } - - _gnutls_mpi_powm(tmp1, v, u, n); - _gnutls_mpi_mulm(tmp2, A, tmp1, n); - _gnutls_mpi_release(&tmp1); - - _gnutls_mpi_powm(S, tmp2, b, n); - _gnutls_mpi_release(&tmp2); - - return S; -} - -/* A = g^a % N - * returns A and a (which is random) - */ -GNUTLS_MPI _gnutls_calc_srp_A(GNUTLS_MPI * a, GNUTLS_MPI g, GNUTLS_MPI n) -{ - GNUTLS_MPI tmpa; - GNUTLS_MPI A; - int bits; - - bits = _gnutls_mpi_get_nbits(n); - tmpa = _gnutls_mpi_new(bits); /* FIXME: allocate in secure memory */ - if (tmpa==NULL) { - gnutls_assert(); - return NULL; - } - - _gnutls_mpi_randomize(tmpa, bits, GCRY_STRONG_RANDOM); - - A = _gnutls_mpi_new(bits); /* FIXME: allocate in secure memory */ - if (A==NULL) { - gnutls_assert(); - _gnutls_mpi_release( &tmpa); - return NULL; - } - _gnutls_mpi_powm(A, g, tmpa, n); - - if (a != NULL) - *a = tmpa; - else - _gnutls_mpi_release(&tmpa); - - return A; -} - -/* generate x = SHA(s | SHA(U | ":" | p)) - * The output is exactly 20 bytes - */ -int _gnutls_calc_srp_sha(char *username, char *password, opaque * salt, - int salt_size, int *size, void* digest) -{ - GNUTLS_HASH_HANDLE td; - opaque res[MAX_HASH_SIZE]; - - *size = 20; - - td = _gnutls_hash_init(GNUTLS_MAC_SHA); - if (td==NULL) { - return GNUTLS_E_MEMORY_ERROR; - } - _gnutls_hash(td, username, strlen(username)); - _gnutls_hash(td, ":", 1); - _gnutls_hash(td, password, strlen(password)); - - _gnutls_hash_deinit(td, res); - - td = _gnutls_hash_init(GNUTLS_MAC_SHA); - if (td==NULL) { - return GNUTLS_E_MEMORY_ERROR; - } - - _gnutls_hash(td, salt, salt_size); - _gnutls_hash(td, res, 20); /* 20 bytes is the output of sha1 */ - - _gnutls_hash_deinit(td, digest); - - return 0; -} - -int _gnutls_calc_srp_x(char *username, char *password, opaque * salt, - int salt_size, uint8 crypt_algo, int *size, void* digest) -{ - - switch (crypt_algo) { - case SRPSHA1_CRYPT: - return _gnutls_calc_srp_sha(username, password, salt, - salt_size, size, digest); - case BLOWFISH_CRYPT: - return _gnutls_calc_srp_bcrypt(username, password, salt, salt_size, - size, digest); - } - return -1; -} - - -/* S = (B - g^x) ^ (a + u * x) % N - * this is our shared key - */ -GNUTLS_MPI _gnutls_calc_srp_S2(GNUTLS_MPI B, GNUTLS_MPI g, GNUTLS_MPI x, GNUTLS_MPI a, GNUTLS_MPI u, GNUTLS_MPI n) -{ - GNUTLS_MPI S, tmp1, tmp2, tmp4; - - S = _gnutls_mpi_alloc_like(n); - if (S==NULL) - return NULL; - - tmp1 = _gnutls_mpi_alloc_like(n); - tmp2 = _gnutls_mpi_alloc_like(n); - if (tmp1 == NULL || tmp2 == NULL) { - _gnutls_mpi_release(&tmp1); - _gnutls_mpi_release(&tmp2); - return NULL; - } - - _gnutls_mpi_powm(tmp1, g, x, n); - - _gnutls_mpi_subm(tmp2, B, tmp1, n); - - tmp4 = _gnutls_mpi_alloc_like(n); - if (tmp4==NULL) - return NULL; - - _gnutls_mpi_mul(tmp1, u, x); - _gnutls_mpi_add(tmp4, a, tmp1); - _gnutls_mpi_release(&tmp1); - - _gnutls_mpi_powm(S, tmp2, tmp4, n); - _gnutls_mpi_release(&tmp2); - _gnutls_mpi_release(&tmp4); - - return S; -} - -/** - * gnutls_srp_free_server_sc - Used to free an allocated GNUTLS_SRP_CLIENT_CREDENTIALS structure - * @sc: is an &GNUTLS_SRP_CLIENT_CREDENTIALS structure. - * - * This structure is complex enough to manipulate directly thus - * this helper function is provided in order to free (deallocate) - * the structure. - **/ -void gnutls_srp_free_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS sc) { - gnutls_free( sc->username); - gnutls_free( sc->password); - gnutls_free( sc); -} - -/** - * gnutls_srp_allocate_server_sc - Used to allocate an GNUTLS_SRP_SERVER_CREDENTIALS structure - * @sc: is a pointer to an &GNUTLS_SRP_SERVER_CREDENTIALS structure. - * - * This structure is complex enough to manipulate directly thus - * this helper function is provided in order to allocate - * the structure. - **/ -int gnutls_srp_allocate_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS *sc) { - *sc = gnutls_calloc( 1, sizeof(SRP_CLIENT_CREDENTIALS_INT)); - - if (*sc==NULL) return GNUTLS_E_MEMORY_ERROR; - - return 0; -} - -/** - * gnutls_srp_set_client_cred - Used to set the username/password, in a GNUTLS_SRP_CLIENT_CREDENTIALS structure - * @res: is an &GNUTLS_SRP_CLIENT_CREDENTIALS structure. - * @username: is the user's userid - * @password: is the user's password - * - **/ -int gnutls_srp_set_client_cred( GNUTLS_SRP_CLIENT_CREDENTIALS res, char *username, char * password) { - - if (username==NULL || password == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_PARAMETERS; - } - - res->username = gnutls_strdup( username); - if (res->username == NULL) return GNUTLS_E_MEMORY_ERROR; - - res->password = gnutls_strdup( password); - if (res->password==NULL) { - gnutls_free(res->username); - return GNUTLS_E_MEMORY_ERROR; - } - - return 0; -} - -/** - * gnutls_srp_free_server_sc - Used to free an allocated GNUTLS_SRP_SERVER_CREDENTIALS structure - * @sc: is an &GNUTLS_SRP_SERVER_CREDENTIALS structure. - * - * This structure is complex enough to manipulate directly thus - * this helper function is provided in order to free (deallocate) - * the structure. - **/ -void gnutls_srp_free_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS sc) { -int i; - for (i=0;ipassword_files;i++) { - gnutls_free( sc->password_file[i]); - gnutls_free( sc->password_conf_file[i]); - } - gnutls_free(sc->password_file); - gnutls_free(sc->password_conf_file); - - gnutls_free(sc); -} - -/** - * gnutls_srp_allocate_server_sc - Used to allocate an GNUTLS_SRP_SERVER_CREDENTIALS structure - * @sc: is a pointer to an &GNUTLS_SRP_SERVER_CREDENTIALS structure. - * - * This structure is complex enough to manipulate directly thus - * this helper function is provided in order to allocate - * the structure. - **/ -int gnutls_srp_allocate_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS *sc) { - *sc = gnutls_calloc( 1, sizeof(SRP_SERVER_CREDENTIALS_INT)); - - if (*sc==NULL) return GNUTLS_E_MEMORY_ERROR; - - return 0; -} - -inline -static int file_exists( const char* file) { -FILE* fd; - - fd = fopen( file, "r"); - if (fd==NULL) return -1; - - fclose(fd); - return 0; -} - -/** - * gnutls_srp_set_server_cred_file - Used to set the password files, in a GNUTLS_SRP_SERVER_CREDENTIALS structure - * @res: is an &GNUTLS_SRP_SERVER_CREDENTIALS structure. - * @password_file: is the SRP password file (tpasswd) - * @password_conf_file: is the SRP password conf file (tpasswd.conf) - * - **/ -int gnutls_srp_set_server_cred_file( GNUTLS_SRP_SERVER_CREDENTIALS res, char *password_file, char * password_conf_file) { -int i; - - if (password_file==NULL || password_conf_file==NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_PARAMETERS; - } - - /* Check if the files can be opened */ - if (file_exists( password_file)!=0) { - gnutls_assert(); - return GNUTLS_E_FILE_ERROR; - } - - if (file_exists( password_conf_file)!=0) { - gnutls_assert(); - return GNUTLS_E_FILE_ERROR; - } - - res->password_file = gnutls_realloc( res->password_file, - sizeof(char*)*(res->password_files+1)); - if (res->password_file==NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - res->password_conf_file = gnutls_realloc( res->password_conf_file, - sizeof(char*)*(res->password_files+1)); - if (res->password_conf_file==NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - i = res->password_files++; - - res->password_file[i] = gnutls_strdup( password_file); - if (res->password_file[i]==NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - res->password_conf_file[i] = gnutls_strdup( password_conf_file); - if (res->password_conf_file[i]==NULL) { - gnutls_assert(); - gnutls_free(res->password_file[i]); - return GNUTLS_E_MEMORY_ERROR; - } - - return 0; -} - -/** - * gnutls_srp_server_set_select_func - Used to set a callback to assist in selecting the proper password file - * @state: is a &GNUTLS_STATE structure. - * @func: is the callback function - * - * The callback's function form is: - * int (*callback)(GNUTLS_STATE, const char** pfiles, const char** pconffiles, int npfiles); - * - * 'pfiles' contains 'npfiles' char* structures which hold - * the password file name. 'pconffiles' contain the corresponding - * conf files. - * - * This function specifies what we, in case of a server, are going - * to do when we have to use a password file. If this callback - * function is not provided then gnutls will automaticaly select the - * first password file - * - * In case the callback returned a negative number then gnutls will - * not attempt to choose the appropriate certificate and the caller function - * will fail. - * - * The callback function will only be called once per handshake. - * The callback function should return the index of the certificate - * choosen by the server. -1 indicates an error. - * - **/ -void gnutls_srp_server_set_select_func(GNUTLS_STATE state, - srp_server_select_func - * func) -{ - state->gnutls_internals.server_srp_callback = func; -} - -/** - * gnutls_srp_server_get_username - This function returns the username of the peer - * @state: is a gnutls state - * - * This function will return the username of the peer. This should only be - * called in case of SRP authentication and in case of a server. - * Returns NULL in case of an error. - * - **/ -const char *gnutls_srp_server_get_username(GNUTLS_STATE state) -{ - SRP_SERVER_AUTH_INFO info; - - CHECK_AUTH(GNUTLS_CRD_SRP, NULL); - - info = _gnutls_get_auth_info(state); - if (info == NULL) - return NULL; - return info->username; -} - - -#else /* NO SRP: so define stubs */ - -const char *gnutls_srp_server_get_username(GNUTLS_STATE state) -{ - return NULL; -} - -void gnutls_srp_free_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS sc) { - return; -} - -int gnutls_srp_allocate_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS *sc) { - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int gnutls_srp_set_client_cred( GNUTLS_SRP_CLIENT_CREDENTIALS res, char *username, char * password) { - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -void gnutls_srp_free_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS sc) { - return; -} - -int gnutls_srp_allocate_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS *sc) { - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -int gnutls_srp_set_server_cred_file( GNUTLS_SRP_SERVER_CREDENTIALS res, char *password_file, char * password_conf_file) { - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -} - -void gnutls_srp_server_set_select_func(GNUTLS_STATE state, - srp_server_select_func - * func) { - return; -} - -#endif /* ENABLE_SRP */ diff --git a/lib/gnutls_srp.h b/lib/gnutls_srp.h deleted file mode 100644 index 5f13abd7c1..0000000000 --- a/lib/gnutls_srp.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifdef ENABLE_SRP - -int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, MPI g, MPI prime); -MPI _gnutls_calc_srp_B(MPI * ret_b, MPI g, MPI n, MPI v); -MPI _gnutls_calc_srp_u( MPI B); -MPI _gnutls_calc_srp_S1(MPI A, MPI b, MPI u, MPI v, MPI n); -MPI _gnutls_calc_srp_A(MPI *a, MPI g, MPI n); -MPI _gnutls_calc_srp_S2(MPI B, MPI g, MPI x, MPI a, MPI u, MPI n); -int _gnutls_calc_srp_x( char* username, char* password, opaque* salt, int salt_size, uint8 crypt_algo, int* size, void* digest); -int _gnutls_srp_gn( opaque** ret_g, opaque** ret_n, int bits); - -/* our prime */ -extern const uint8 diffie_hellman_group1_prime[130]; - -/* g is defined to be 2 */ -#define SRP_MAX_HASH_SIZE 24 - -#endif diff --git a/libextra/Makefile.am b/libextra/Makefile.am new file mode 100644 index 0000000000..d5615a3e39 --- /dev/null +++ b/libextra/Makefile.am @@ -0,0 +1,26 @@ +INCLUDES = -I../lib +include_HEADERS = gnutls-extra.h + +EXTRA_DIST = ext_srp.h crypt_bcrypt.h crypt_srpsha1.h gnutls_srp.h \ + auth_srp.h auth_srp_passwd.h crypt.h gnutls_openpgp.h + gnutls-extra-api.tex gnutls_extra.h + +lib_LTLIBRARIES = libgnutls-extra.la + + +COBJECTS_EXTRA = crypt_bcrypt.c crypt.c crypt_srpsha1.c ext_srp.c \ + gnutls_srp.c auth_srp.c auth_srp_passwd.c auth_srp_sb64.c \ + gnutls_openpgp.c gnutls_extra.c + +libgnutls_extra_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) + +libgnutls_extra_la_SOURCES = $(COBJECTS_EXTRA) + +gnutls-extra-api.tex: $(COBJECTS_EXTRA) + @echo "" > gnutls-extra-api.tex + @for i in $(COBJECTS_EXTRA); \ + do echo -n "Creating documentation for file $$i... " && ../doc/scripts/gdoc -tex $$i >> gnutls-extra-api.tex \ + && echo "ok"; \ + done + +all-local: gnutls-extra-api.tex diff --git a/libextra/auth_srp.c b/libextra/auth_srp.c new file mode 100644 index 0000000000..45f0295335 --- /dev/null +++ b/libextra/auth_srp.c @@ -0,0 +1,448 @@ +/* + * Copyright (C) 2001 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * GNUTLS 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 2 of the License, or + * (at your option) any later version. + * + * GNUTLS 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "gnutls_int.h" + +#ifdef ENABLE_SRP + +#include "gnutls_errors.h" +#include "auth_srp_passwd.h" +#include "gnutls_auth.h" +#include "gnutls_auth_int.h" +#include "gnutls_srp.h" +#include "debug.h" +#include "gnutls_num.h" +#include "auth_srp.h" +#include + +int gen_srp_server_kx2(GNUTLS_STATE, opaque **); +int gen_srp_client_kx0(GNUTLS_STATE, opaque **); + +int proc_srp_server_kx2(GNUTLS_STATE, opaque *, int); +int proc_srp_client_kx0(GNUTLS_STATE, opaque *, int); + +const MOD_AUTH_STRUCT srp_auth_struct = { + "SRP", + NULL, + NULL, + NULL, + gen_srp_server_kx2, + gen_srp_client_kx0, + NULL, + NULL, + NULL, + + NULL, + NULL, /* certificate */ + NULL, + proc_srp_server_kx2, + proc_srp_client_kx0, + NULL, + NULL, + NULL +}; + + +#define _b state->gnutls_key->b +#define B state->gnutls_key->B +#define _a state->gnutls_key->a +#define A state->gnutls_key->A +#define N state->gnutls_key->client_p +#define G state->gnutls_key->client_g +#define V state->gnutls_key->x +#define S state->gnutls_key->KEY + +/* Send the first key exchange message ( g, n, s) and append the verifier algorithm number + * Data is allocated by the caller, and should have data_size size. + */ +int gen_srp_server_hello(GNUTLS_STATE state, opaque * data, int data_size) +{ + size_t n_g, n_n, n_s; + size_t ret; + uint8 *data_n, *data_s; + uint8 *data_g, *username; + uint8 pwd_algo; + GNUTLS_SRP_PWD_ENTRY *pwd_entry; + int err; + SRP_SERVER_AUTH_INFO info; + + if ( (ret=_gnutls_auth_info_set( state, GNUTLS_CRD_SRP, sizeof( SRP_SERVER_AUTH_INFO_INT), 1)) < 0) { + gnutls_assert(); + return ret; + } + + info = _gnutls_get_auth_info( state); + username = info->username; + + _gnutls_str_cpy( username, MAX_SRP_USERNAME, state->security_parameters.extensions.srp_username); + + pwd_entry = _gnutls_srp_pwd_read_entry( state, username, &err); + + if (pwd_entry == NULL) { + if (err==0) + /* in order to avoid informing the peer that + * username does not exist. + */ + pwd_entry = _gnutls_randomize_pwd_entry(); + else + return GNUTLS_E_PWD_ERROR; + } + + pwd_algo = (uint8) pwd_entry->algorithm; + + if (_gnutls_mpi_print( NULL, &n_g, pwd_entry->g)!=0) { + gnutls_assert(); + return GNUTLS_E_MPI_PRINT_FAILED; + } + if (_gnutls_mpi_print( NULL, &n_n, pwd_entry->n)!=0) { + gnutls_assert(); + return GNUTLS_E_MPI_PRINT_FAILED; + } + + /* copy from pwd_entry to local variables (actually in state) */ + G = _gnutls_mpi_alloc_like(pwd_entry->g); + N = _gnutls_mpi_alloc_like(pwd_entry->n); + V = _gnutls_mpi_alloc_like(pwd_entry->v); + + if (G==NULL || N == NULL || V == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + _gnutls_mpi_set(G, pwd_entry->g); + _gnutls_mpi_set(N, pwd_entry->n); + _gnutls_mpi_set(V, pwd_entry->v); + + if (data_size < n_n + n_g + pwd_entry->salt_size + 6 + 1) { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + data_g = data; + + /* firstly copy the algorithm used to generate the verifier + */ + data_g[0] = pwd_algo; + + /* copy G (generator) to data */ + + data_g++; + + if(_gnutls_mpi_print( &data_g[2], &n_g, G)!=0) { + gnutls_assert(); + return GNUTLS_E_MPI_PRINT_FAILED; + } + + WRITEuint16( n_g, data_g); + + /* copy N (mod n) */ + data_n = &data_g[2 + n_g]; + + if (_gnutls_mpi_print( &data_n[2], &n_n, N)!=0) { + gnutls_assert(); + return GNUTLS_E_MPI_PRINT_FAILED; + } + + WRITEuint16( n_n, data_n); + + /* copy the salt */ + data_s = &data_n[2 + n_n]; + n_s = pwd_entry->salt_size; + memcpy(&data_s[2], pwd_entry->salt, n_s); + + WRITEuint16( n_s, data_s); + + ret = n_g + n_n + pwd_entry->salt_size + 6 + 1; + _gnutls_srp_clear_pwd_entry( pwd_entry); + + return ret; +} + +/* send the second key exchange message */ +int gen_srp_server_kx2(GNUTLS_STATE state, opaque ** data) +{ + int ret; + size_t n_b; + uint8 *data_b; + + /* calculate: B = (v + g^b) % N */ + B = _gnutls_calc_srp_B( &_b, G, N, V); + if (B==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + if (_gnutls_mpi_print( NULL, &n_b, B)!=0) + return GNUTLS_E_MPI_PRINT_FAILED; + + (*data) = gnutls_malloc(n_b + 2); + if ( (*data) == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + /* copy B */ + data_b = (*data); + if (_gnutls_mpi_print( &data_b[2], &n_b, B)!=0) + return GNUTLS_E_MPI_PRINT_FAILED; + + WRITEuint16( n_b, data_b); + + /* calculate u */ + state->gnutls_key->u = _gnutls_calc_srp_u(B); + if (state->gnutls_key->u==NULL) { + gnutls_assert(); + gnutls_free( *data); + return GNUTLS_E_MEMORY_ERROR; + } + + /* S = (A * v^u) ^ b % N */ + S = _gnutls_calc_srp_S1( A, _b, state->gnutls_key->u, V, N); + if ( S==NULL) { + gnutls_assert(); + gnutls_free( *data); + return GNUTLS_E_MEMORY_ERROR; + } + + _gnutls_mpi_release(&A); + _gnutls_mpi_release(&_b); + _gnutls_mpi_release(&V); + _gnutls_mpi_release(&state->gnutls_key->u); + _gnutls_mpi_release(&B); + + ret = _gnutls_generate_key( state->gnutls_key); + _gnutls_mpi_release( &S); + + if (ret < 0) + return ret; + + return n_b + 2; +} + + +/* return A = g^a % N */ +int gen_srp_client_kx0(GNUTLS_STATE state, opaque ** data) +{ + size_t n_a; + uint8 *data_a; + char *username; + char *password; + const GNUTLS_SRP_CLIENT_CREDENTIALS cred = + _gnutls_get_cred(state->gnutls_key, GNUTLS_CRD_SRP, NULL); + + if (cred == NULL) { + gnutls_assert(); + return GNUTLS_E_INSUFICIENT_CRED; + } + + username = cred->username; + password = cred->password; + + if (username == NULL || password == NULL) + return GNUTLS_E_INSUFICIENT_CRED; + + /* calc A = g^a % N */ + if (G == NULL || N == NULL) { + gnutls_assert(); + return GNUTLS_E_INSUFICIENT_CRED; + } + + A = _gnutls_calc_srp_A( &_a, G, N); + if (A==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + if (_gnutls_mpi_print( NULL, &n_a, A)!=0) + return GNUTLS_E_MPI_PRINT_FAILED; + + (*data) = gnutls_malloc(n_a + 2); + if ( (*data) == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + /* copy A */ + data_a = (*data); + if (_gnutls_mpi_print( &data_a[2], &n_a, A)!=0) { + gnutls_free( *data); + return GNUTLS_E_MPI_PRINT_FAILED; + } + + WRITEuint16( n_a, data_a); + + return n_a + 2; +} + +/* receive the first key exchange message ( g, n, s) */ +int proc_srp_server_hello(GNUTLS_STATE state, const opaque * data, int data_size) +{ + uint16 n_s, n_g, n_n; + size_t _n_s, _n_g, _n_n; + const uint8 *data_n; + const uint8 *data_g; + const uint8 *data_s; + uint8 pwd_algo; + int i, ret; + opaque hd[SRP_MAX_HASH_SIZE]; + char *username; + char *password; + const GNUTLS_SRP_CLIENT_CREDENTIALS cred = + _gnutls_get_cred(state->gnutls_key, GNUTLS_CRD_SRP, NULL); + + if (cred == NULL) { + gnutls_assert(); + return GNUTLS_E_INSUFICIENT_CRED; + } + + username = cred->username; + password = cred->password; + + if (username == NULL || password == NULL) + return GNUTLS_E_INSUFICIENT_CRED; + +/* read the algorithm used to generate V */ + + i = 0; + DECR_LEN( data_size, 1); + pwd_algo = data[0]; + i++; + + DECR_LEN( data_size, 2); + n_g = READuint16( &data[i]); + i += 2; + + DECR_LEN( data_size, n_g); + data_g = &data[i]; + i += n_g; + if (i > data_size) { + gnutls_assert(); + return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; + } + + DECR_LEN( data_size, 2); + n_n = READuint16( &data[i]); + i += 2; + + DECR_LEN( data_size, n_n); + data_n = &data[i]; + i += n_n; + + DECR_LEN( data_size, 2); + n_s = READuint16( &data[i]); + i += 2; + + DECR_LEN( data_size, n_s); + data_s = &data[i]; + i += n_s; + + _n_s = n_s; + _n_g = n_g; + _n_n = n_n; + + if (_gnutls_mpi_scan(&N, data_n, &_n_n) != 0 || N == NULL) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + if (_gnutls_mpi_scan(&G, data_g, &_n_g) != 0 || G == NULL) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + /* generate x = SHA(s | SHA(U | ":" | p)) + * (or the equivalent using bcrypt) + */ + if ( ( ret =_gnutls_calc_srp_x( username, password, (opaque*)data_s, n_s, pwd_algo, &_n_g, hd)) < 0) { + gnutls_assert(); + return ret; + } + + if (_gnutls_mpi_scan(&state->gnutls_key->x, hd, &_n_g) != 0 || state->gnutls_key->x==NULL) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + return 0; +} + +/* just read A and put it to state */ +int proc_srp_client_kx0(GNUTLS_STATE state, opaque * data, int data_size) +{ + size_t _n_A; + + DECR_LEN( data_size, 2); + _n_A = READuint16( &data[0]); + + DECR_LEN( data_size, _n_A); + if (_gnutls_mpi_scan(&A, &data[2], &_n_A) || A == NULL) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + return 0; +} + + +int proc_srp_server_kx2(GNUTLS_STATE state, opaque * data, int data_size) +{ + size_t _n_B; + int ret; + + DECR_LEN( data_size, 2); + _n_B = READuint16( &data[0]); + + DECR_LEN( data_size, _n_B); + if (_gnutls_mpi_scan(&B, &data[2], &_n_B) || B==NULL) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + /* calculate u */ + state->gnutls_key->u = _gnutls_calc_srp_u( B); + if ( state->gnutls_key->u == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + /* S = (B - g^x) ^ (a + u * x) % N */ + S = _gnutls_calc_srp_S2( B, G, state->gnutls_key->x, _a, state->gnutls_key->u, N); + if (S==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + + _gnutls_mpi_release(&A); + _gnutls_mpi_release(&_b); + _gnutls_mpi_release(&V); + _gnutls_mpi_release(&state->gnutls_key->u); + _gnutls_mpi_release(&B); + + ret = _gnutls_generate_key( state->gnutls_key); + _gnutls_mpi_release(&S); + + if (ret < 0) + return ret; + + return 0; +} + +#endif /* ENABLE_SRP */ diff --git a/libextra/auth_srp.h b/libextra/auth_srp.h new file mode 100644 index 0000000000..a01475b9a6 --- /dev/null +++ b/libextra/auth_srp.h @@ -0,0 +1,31 @@ +#include + + +typedef struct { + char* username; + char* password; +} SRP_CLIENT_CREDENTIALS_INT; + +#define GNUTLS_SRP_CLIENT_CREDENTIALS SRP_CLIENT_CREDENTIALS_INT* + +typedef struct { + char** password_file; + char** password_conf_file; + int password_files; +} SRP_SERVER_CREDENTIALS_INT; + +#define GNUTLS_SRP_SERVER_CREDENTIALS SRP_SERVER_CREDENTIALS_INT* + +/* these structures should not use allocated data */ +typedef struct SRP_SERVER_AUTH_INFO_INT { + char username[MAX_SRP_USERNAME]; +} *SRP_SERVER_AUTH_INFO; + +#ifdef ENABLE_SRP + +int proc_srp_server_hello(GNUTLS_STATE state, const opaque * data, int data_size); +int gen_srp_server_hello(GNUTLS_STATE state, opaque * data, int data_size); + +typedef struct SRP_SERVER_AUTH_INFO_INT SRP_SERVER_AUTH_INFO_INT; + +#endif /* ENABLE_SRP */ diff --git a/libextra/auth_srp_passwd.c b/libextra/auth_srp_passwd.c new file mode 100644 index 0000000000..d47df6ec7a --- /dev/null +++ b/libextra/auth_srp_passwd.c @@ -0,0 +1,433 @@ +/* + * Copyright (C) 2001 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * GNUTLS 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 2 of the License, or + * (at your option) any later version. + * + * GNUTLS 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/* Functions for operating in an SRP passwd file are included here */ + +#include "gnutls_int.h" + +#ifdef ENABLE_SRP + +#include "x509_b64.h" +#include "gnutls_errors.h" +#include "auth_srp_passwd.h" +#include "auth_srp.h" +#include "gnutls_auth_int.h" +#include "gnutls_srp.h" +#include "gnutls_random.h" +#include "gnutls_dh.h" +#include "debug.h" +#include + +/* this function parses tpasswd.conf file. Format is: + * string(username):base64(v):base64(salt):int(index) + */ +static int pwd_put_values( GNUTLS_SRP_PWD_ENTRY *entry, char *str, int str_size) { +char * p, *p2; +int len; +opaque *verifier; +int verifier_size; +int indx; + + p = rindex( str, ':'); /* we have index */ + if (p==NULL) { + gnutls_assert(); + return GNUTLS_E_PARSING_ERROR; + } + + *p='\0'; + p++; + + len = strlen(p); + indx = atoi(p); + if (indx==0) { + gnutls_assert(); + return GNUTLS_E_PARSING_ERROR; + } + + /* now go for salt */ + p = rindex( str, ':'); /* we have salt */ + if (p==NULL) { + gnutls_assert(); + return GNUTLS_E_PARSING_ERROR; + } + + *p='\0'; + p++; + + len = strlen(p); + + entry->salt_size = _gnutls_sbase64_decode( p, len, &entry->salt); + + if (entry->salt_size <= 0) { + gnutls_assert(); + return GNUTLS_E_PARSING_ERROR; + } + + /* now go for verifier */ + p = rindex( str, ':'); /* we have verifier */ + if (p==NULL) { + gnutls_free(entry->salt); + return GNUTLS_E_PARSING_ERROR; + } + + *p='\0'; + p++; + + if ( (p2 = index(p, '$')) == NULL) { + entry->algorithm = SRPSHA1_CRYPT; + } else { + p++; + entry->algorithm = atoi(p); + p2 = index(p, '$'); /* find the last $ */ + if (p2==NULL) { + gnutls_assert(); + gnutls_free(entry->salt); + return GNUTLS_E_PARSING_ERROR; + } + p = p2+1; + } + + len = strlen(p); + verifier_size = _gnutls_sbase64_decode( p, len, &verifier); + if (verifier_size <= 0) { + gnutls_assert(); + gnutls_free(entry->salt); + return GNUTLS_E_PARSING_ERROR; + } + + if (_gnutls_mpi_scan(&entry->v, verifier, &verifier_size) || entry->v == NULL) { + gnutls_assert(); + gnutls_free( entry->salt); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + gnutls_free( verifier); + + /* now go for username */ + *p='\0'; + + entry->username = gnutls_strdup(str); + if (entry->username==NULL) { + gnutls_free( entry->salt); + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + return indx; +} + + +/* this function parses tpasswd.conf file. Format is: + * int(index):base64(n):int(g) + */ +static int pwd_put_values2( GNUTLS_SRP_PWD_ENTRY *entry, char *str, int str_size) { +char * p; +int len; +opaque * tmp; +int tmp_size; + + p = rindex( str, ':'); /* we have g */ + if (p==NULL) { + gnutls_assert(); + return GNUTLS_E_PARSING_ERROR; + } + + *p='\0'; + p++; + + /* read the generator */ + len = strlen(p); + if (p[len-1]=='\n' || p[len-1]==' ') len--; + tmp_size = _gnutls_sbase64_decode( p, len, &tmp); + + if (tmp_size < 0) { + gnutls_assert(); + return GNUTLS_E_PARSING_ERROR; + } + if (_gnutls_mpi_scan(&entry->g, tmp, &tmp_size) || entry->g==NULL) { + gnutls_assert(); + gnutls_free(tmp); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + gnutls_free(tmp); + + + /* now go for n - modulo */ + p = rindex( str, ':'); /* we have n */ + if (p==NULL) { + _gnutls_mpi_release(&entry->g); + gnutls_assert(); + return GNUTLS_E_PARSING_ERROR; + } + + *p='\0'; + p++; + + len = strlen(p); + tmp_size = _gnutls_sbase64_decode( p, len, &tmp); + + if (tmp_size < 0) { + gnutls_assert(); + _gnutls_mpi_release(&entry->g); + return GNUTLS_E_PARSING_ERROR; + } + if (_gnutls_mpi_scan(&entry->n, tmp, &tmp_size) || entry->n==NULL) { + gnutls_assert(); + gnutls_free(tmp); + _gnutls_mpi_release(&entry->g); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + gnutls_free(tmp); + + return 0; +} + + +/* this function opens the tpasswd.conf file + */ +static int pwd_read_conf( const char* pconf_file, GNUTLS_SRP_PWD_ENTRY* entry, int index) { + FILE * fd; + char line[2*1024]; + int i; + char indexstr[10]; + + sprintf( indexstr, "%d", index); /* Flawfinder: ignore */ + + fd = fopen( pconf_file, "r"); + if (fd==NULL) { + gnutls_assert(); + return GNUTLS_E_FILE_ERROR; + } + + while( fgets( line, sizeof(line), fd) != NULL) { + /* move to first ':' */ + i=0; + while( (line[i]!=':') && (line[i]!='\0') && (i < sizeof(line)) ) { + i++; + } + if (strncmp( indexstr, line, strlen(indexstr)) == 0) { + if ((index = pwd_put_values2( entry, line, strlen(line))) >= 0) + return 0; + else { + return GNUTLS_E_PWD_ERROR; + } + } + } + return GNUTLS_E_PWD_ERROR; + +} + + +GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_STATE state, char* username, int *err) { + const GNUTLS_SRP_SERVER_CREDENTIALS cred; + FILE * fd; + char line[2*1024]; + int i, len; + GNUTLS_SRP_PWD_ENTRY * entry = gnutls_malloc(sizeof(GNUTLS_SRP_PWD_ENTRY)); + int index; + int pwd_index = 0; + + if (entry==NULL) { + gnutls_assert(); + *err = 1; + return NULL; + } + + *err = 0; /* normal exit */ + + cred = _gnutls_get_cred( state->gnutls_key, GNUTLS_CRD_SRP, NULL); + if (cred==NULL) { + *err = 1; + gnutls_assert(); + gnutls_free(entry); + return NULL; + } + + if (cred->password_files<=0) { + gnutls_assert(); + return NULL; + } + + /* use the callback to select a password file */ + if (state->gnutls_internals.server_srp_callback!=NULL) { + pwd_index = state->gnutls_internals.server_srp_callback( + state, cred->password_file, cred->password_conf_file, + cred->password_files); + + if (pwd_index < 0) { + gnutls_assert(); + return NULL; + } + } + + fd = fopen( cred->password_file[pwd_index], "r"); + if (fd==NULL) { + *err = 1; /* failed due to critical error */ + gnutls_assert(); + gnutls_free(entry); + return NULL; + } + + while( fgets( line, sizeof(line), fd) != NULL) { + /* move to first ':' */ + i=0; + while( (line[i]!=':') && (line[i]!='\0') && (i < sizeof(line)) ) { + i++; + } + len = strlen(username); + if (strncmp( username, line, (i>len)?i:len) == 0) { + if ((index = pwd_put_values( entry, line, strlen(line))) >= 0) + if (pwd_read_conf( cred->password_conf_file[pwd_index], entry, index)==0) { + return entry; + } else { + gnutls_free(entry); + return NULL; + } + else { + gnutls_free(entry); + return NULL; + } + } + } + return NULL; + +} +#define RNDUSER "rnd" +#define RND_SALT_SIZE 17 +GNUTLS_SRP_PWD_ENTRY* _gnutls_randomize_pwd_entry() { + GNUTLS_SRP_PWD_ENTRY * pwd_entry = gnutls_calloc(1, sizeof(GNUTLS_SRP_PWD_ENTRY)); + + if (pwd_entry == NULL) { + gnutls_assert(); + return NULL; + } + + pwd_entry->g = _gnutls_get_rnd_srp_params( &pwd_entry->n, 1024); + if (pwd_entry->g==NULL || pwd_entry->n==NULL) { + gnutls_assert(); + _gnutls_srp_clear_pwd_entry( pwd_entry); + return NULL; + } + + pwd_entry->username = gnutls_malloc(strlen(RNDUSER)+1); + if (pwd_entry->username == NULL) { + gnutls_assert(); + _gnutls_srp_clear_pwd_entry( pwd_entry); + return NULL; + } + _gnutls_str_cpy( pwd_entry->username, MAX_SRP_USERNAME, RNDUSER); /* Flawfinder: ignore */ + + pwd_entry->v = _gnutls_mpi_new(160); + if (pwd_entry->v==NULL) { + gnutls_assert(); + _gnutls_srp_clear_pwd_entry( pwd_entry); + return NULL; + } + + _gnutls_mpi_randomize( pwd_entry->v, 160, GCRY_WEAK_RANDOM); + + pwd_entry->salt_size = RND_SALT_SIZE; + + pwd_entry->salt = gnutls_malloc(RND_SALT_SIZE); + if (pwd_entry->salt==NULL) { + gnutls_assert(); + _gnutls_srp_clear_pwd_entry( pwd_entry); + return NULL; + } + + if (_gnutls_get_random(pwd_entry->salt, RND_SALT_SIZE, GNUTLS_WEAK_RANDOM) < 0) { + gnutls_assert(); + _gnutls_srp_clear_pwd_entry( pwd_entry); + return NULL; + } + + pwd_entry->algorithm = 0; + + return pwd_entry; + +} + +void _gnutls_srp_clear_pwd_entry( GNUTLS_SRP_PWD_ENTRY * entry) { + _gnutls_mpi_release(&entry->v); + _gnutls_mpi_release(&entry->g); + _gnutls_mpi_release(&entry->n); + + gnutls_free(entry->salt); + gnutls_free(entry->username); + + gnutls_free(entry); + + return; +} + +/* Generates a prime and a generator, and returns the srpbase64 encoded value. + */ +int _gnutls_srp_generate_prime(opaque ** ret_g, opaque ** ret_n, int bits) +{ + + GNUTLS_MPI prime, g; + int siz; + char *tmp; + + if ( _gnutls_dh_generate_prime(&g, &prime, bits) < 0) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + siz = 0; + _gnutls_mpi_print( NULL, &siz, g); + if (ret_g != NULL) { + tmp = gnutls_malloc(siz); + if (tmp==NULL) return GNUTLS_E_MEMORY_ERROR; + + _gnutls_mpi_print( tmp, &siz, g); + + if (_gnutls_sbase64_encode(tmp, siz, ret_g) < 0) { + gnutls_free(tmp); + return GNUTLS_E_UNKNOWN_ERROR; + } + gnutls_free(tmp); + } + + siz = 0; + _gnutls_mpi_print( NULL, &siz, prime); + if (ret_n != NULL) { + tmp = gnutls_malloc(siz); + if (tmp==NULL) return GNUTLS_E_MEMORY_ERROR; + + _gnutls_mpi_print( tmp, &siz, prime); + if (_gnutls_sbase64_encode(tmp, siz, ret_n) < 0) { + gnutls_free(tmp); + return GNUTLS_E_UNKNOWN_ERROR; + } + + gnutls_free(tmp); + } + + _gnutls_mpi_release(&g); + _gnutls_mpi_release(&prime); + + return 0; + +} + +#endif /* ENABLE SRP */ diff --git a/libextra/auth_srp_passwd.h b/libextra/auth_srp_passwd.h new file mode 100644 index 0000000000..6207265542 --- /dev/null +++ b/libextra/auth_srp_passwd.h @@ -0,0 +1,22 @@ +#ifdef ENABLE_SRP + +typedef struct { + char* username; + int algorithm; + + opaque *salt; + int salt_size; + + MPI v; + MPI g; + MPI n; +} GNUTLS_SRP_PWD_ENTRY; + +/* this is localy alocated. It should be freed using the provided function */ +GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_STATE state, char* username, int* err); +void _gnutls_srp_clear_pwd_entry( GNUTLS_SRP_PWD_ENTRY * entry); +GNUTLS_SRP_PWD_ENTRY* _gnutls_randomize_pwd_entry(void); +int _gnutls_sbase64_encode(uint8 * data, int data_size, uint8 ** result); +int _gnutls_sbase64_decode(uint8 * data, int data_size, uint8 ** result); + +#endif /* ENABLE_SRP */ diff --git a/libextra/auth_srp_sb64.c b/libextra/auth_srp_sb64.c new file mode 100644 index 0000000000..3876ed5a6a --- /dev/null +++ b/libextra/auth_srp_sb64.c @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2001 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * GNUTLS 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 2 of the License, or + * (at your option) any later version. + * + * GNUTLS 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "gnutls_int.h" + +#ifdef ENABLE_SRP + +/* this a modified base64 for srp !!! + * It seems that everybody makes it's own base64 convertion. + */ +const static uint8 b64table[64] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./"; + +const static uint8 asciitable[128] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3e, 0x3f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, + 0x23, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, + 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, + 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, + 0xff, 0xff +}; + +inline static int encode(uint8 * result, const uint8 * rdata, int left) +{ + + int data_len; + int c, ret = 4; + uint8 data[3]; + + if (left > 3) + data_len = 3; + else + data_len = left; + + data[0] = data[1] = data[2] = 0; + memcpy(data, rdata, data_len); + + switch (data_len) { + case 3: + result[0] = b64table[((data[0] & 0xfc) >> 2)]; + result[1] = + b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff) | + ((data[1] & 0xf0) >> 4))]; + result[2] = + b64table[((((data[1] & 0x0f) << 2) & 0xff) | + ((data[2] & 0xc0) >> 6))]; + result[3] = b64table[(data[2] & 0x3f) & 0xff]; + break; + case 2: + if ((c = ((data[0] & 0xf0) >> 4)) != 0) { + result[0] = b64table[c]; + result[1] = + b64table[((((data[0] & 0x0f) << 2) & 0xff) | + ((data[1] & 0xc0) >> 6))]; + result[2] = b64table[(data[1] & 0x3f) & 0xff]; + result[3] = '\0'; + ret -= 1; + } else { + if ((c = + ((data[0] & 0x0f) << 2) | ((data[1] & 0xc0) >> + 6)) != 0) { + result[0] = b64table[c]; + result[1] = b64table[data[1] & 0x3f]; + result[2] = '\0'; + result[3] = '\0'; + ret -= 2; + } else { + result[0] = b64table[data[0] & 0x3f]; + result[1] = '\0'; + result[2] = '\0'; + result[3] = '\0'; + ret -= 3; + } + } + break; + case 1: + if ((c = ((data[0] & 0xc0) >> 6)) != 0) { + result[0] = b64table[c]; + result[1] = b64table[(data[0] & 0x3f) & 0xff]; + result[2] = '\0'; + result[3] = '\0'; + ret -= 2; + } else { + result[0] = b64table[(data[0] & 0x3f) & 0xff]; + result[1] = '\0'; + result[2] = '\0'; + result[3] = '\0'; + ret -= 3; + } + break; + default: + return -1; + } + + return ret; + +} + +/* encodes data and puts the result into result (localy alocated) + * The result_size is the return value + */ +int _gnutls_sbase64_encode(uint8 * data, int data_size, uint8 ** result) +{ + int ret, tmp, j, i; + char tmpres[4]; + int mod = data_size % 3; + + ret = mod; + if (ret != 0) + ret = 4; + else + ret = 0; + + ret += (data_size * 4) / 3; + + (*result) = gnutls_calloc( 1, ret + 1); + if ((*result) == NULL) + return -1; + + i = j = 0; +/* encode the bytes that are not a multiple of 3 + */ + if (mod > 0) { + tmp = encode(tmpres, &data[0], mod); + if (tmp < 0) { + gnutls_free( (*result)); + return tmp; + } + + memcpy(&(*result)[0], tmpres, tmp); + i = mod; + j = tmp; + + } +/* encode the rest + */ + for (; i < data_size; i += 3, j += 4) { + tmp = encode(tmpres, &data[i], data_size - i); + if (tmp < 0) { + gnutls_free( (*result)); + return tmp; + } + memcpy(&(*result)[j], tmpres, tmp); + } + + return strlen(*result); +} + + +/* data must be 4 bytes + * result should be 3 bytes + */ +#define TOASCII(c) (c < 127 ? asciitable[c] : 0xff) +inline static int decode(uint8 * result, const uint8 * data) +{ + uint8 a1, a2; + int ret = 3; + + memset( result, 0, 3); + + a1 = TOASCII(data[3]); + a2 = TOASCII(data[2]); + if (a1 != 0xff) result[2] = a1 & 0xff; + else return -1; + if (a2 != 0xff) result[2] |= ((a2 & 0x03) << 6) & 0xff; + + a1 = a2; + a2 = TOASCII(data[1]); + if (a1 != 0xff) result[1] = ((a1 & 0x3c) >> 2); + if (a2 != 0xff) result[1] |= ((a2 & 0x0f) << 4); + else if (a1==0xff || result[1] == 0) ret--; + + a1 = a2; + a2 = TOASCII(data[0]); + if (a1 != 0xff) result[0] = (((a1 & 0x30) >> 4) & 0xff); + if (a2 != 0xff) result[0] |= ((a2 << 2) & 0xff); + else if (a1==0xff || result[0] == 0) ret--; + + return ret; +} + +/* decodes data and puts the result into result (localy alocated) + * The result_size is the return value. + * That function does not ignore newlines tabs etc. You should remove them + * before calling it. + */ +int _gnutls_sbase64_decode(uint8 * data, int idata_size, uint8 ** result) +{ + int i, ret, j, left; + int data_size, tmp; + uint8 datrev[4]; + uint8 tmpres[3]; + + data_size = (idata_size/4)*4; + left = idata_size % 4; + + ret = (data_size / 4) * 3; + + if (left > 0) + ret += 3; + + (*result) = gnutls_malloc(ret+1); + if ((*result) == NULL) + return -1; + + /* the first "block" is treated with special care */ + tmp = 0; + if (left > 0) { + memset( datrev, 0, 4); + memcpy( &datrev[4-left], data, left); + + tmp = decode( tmpres, datrev); + if (tmp < 0) { + gnutls_free( (*result)); + return tmp; + } + + memcpy( *result, &tmpres[3-tmp], tmp); + if (tmp < 3) + ret -= (3 - tmp); + } + + /* rest data */ + for (i = left, j = tmp; i < idata_size; i += 4) { + tmp = decode(tmpres, &data[i]); + if (tmp < 0) { + gnutls_free( (*result)); + return tmp; + } + memcpy(&(*result)[j], tmpres, tmp); + if (tmp < 3) + ret -= (3 - tmp); + j += 3; + } + + return ret; +} + +#ifdef B64_TEST +int main() +{ + char x[100 * 1024]; + int siz; + uint8 *b64; + +/* for (i = 0; i < 128; i++) { + if (i % 6 == 0) + fprintf(stdout, "\n"); + if (strchr(b64table, i) == NULL) + fprintf(stdout, "0x%.2x, ", 0xff); + else + fprintf(stdout, "0x%.2x, ", + (int) ((int) index(b64table, i) - + (int) b64table)); + + + } + return 0;*/ + siz = fread(x, 1, sizeof(x), stdin); + +// siz = _gnutls_sbase64_encode(x, siz, &b64); + siz = _gnutls_sbase64_decode(x, siz, &b64); + + + if (siz < 0) { + _gnutls_log( "ERROR %d\n", siz); + exit(1); + } + + fwrite(b64, siz, 1, stdout); + return 0; + + +} +#endif + +#endif /* ENABLE_SRP */ diff --git a/libextra/crypt.c b/libextra/crypt.c new file mode 100644 index 0000000000..6da9c339b5 --- /dev/null +++ b/libextra/crypt.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2000,2001 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * GNUTLS 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 2 of the License, or + * (at your option) any later version. + * + * GNUTLS 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "gnutls_int.h" + +#ifdef ENABLE_SRP + +#include "crypt_bcrypt.h" +#include "crypt_srpsha1.h" +#include "gnutls_random.h" + +char * gnutls_crypt(const char* username, const char *passwd, crypt_algo algo, int salt, GNUTLS_MPI g, GNUTLS_MPI n) { + + switch(algo) { + case BLOWFISH_CRYPT: /* bcrypt */ + /* salt in bcrypt is actually the cost */ + return crypt_bcrypt_wrapper(username, passwd, salt, g, n); + case SRPSHA1_CRYPT: /* bcrypt */ + /* salt in bcrypt is the salt size */ + return crypt_srpsha1_wrapper(username, passwd, salt, g, n); + } + return NULL; +} + +int gnutls_crypt_vrfy(const char* username, const char *passwd, char* salt, GNUTLS_MPI g, GNUTLS_MPI n) { + char* cr; + + switch(salt[0]) { + case '$': + switch(salt[1]) { + case '2': + cr = crypt_bcrypt(username, passwd, salt, g, n); + if (cr==NULL) return 1; + if (strncmp(cr, salt, strlen(cr))==0) return 0; + break; + } + default: + cr = crypt_srpsha1(username, passwd, salt, g, n); + if (cr==NULL) return 1; + if (strncmp(cr, salt, strlen(cr))==0) return 0; + break; + } + return 1; +} + +#endif diff --git a/libextra/crypt.h b/libextra/crypt.h new file mode 100644 index 0000000000..205ec72136 --- /dev/null +++ b/libextra/crypt.h @@ -0,0 +1,4 @@ +/* crypt functions */ + +char * gnutls_crypt(const char* username, const char *passwd, crypt_algo algo, int salt, MPI g, MPI n); +int gnutls_crypt_vrfy(const char* username, const char *passwd, char* salt, MPI g, MPI n); diff --git a/libextra/crypt_bcrypt.c b/libextra/crypt_bcrypt.c new file mode 100644 index 0000000000..55ece44c4b --- /dev/null +++ b/libextra/crypt_bcrypt.c @@ -0,0 +1,773 @@ +/* + * Copyright (C) 2000,2001 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * GNUTLS 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 2 of the License, or + * (at your option) any later version. + * + * GNUTLS 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/* + * This is a modified version of the blowfish algorithm. + * It is an implementation of the bcrypt algorithm as described + * in a usenix paper by Niels Provos and David Mazieres. + * This is the encoding algorithm used in OpenBSD for passwords. + * (includes a modified version of b64.c) + */ + +/* The differences here from the original openbsd bcrypt algorithm are: + * 1. we use a different b64 hash function + * (the one used in SRP password files), + * 2. we use all the bytes from the encryption step (openbsd omited one byte), + * 3. we use the first 24 bytes of CONCAT(username,NULL,"Orphean...") as the + * encryption string. + */ + +#include "gnutls_int.h" + +#ifdef ENABLE_SRP + +#include "crypt_bcrypt.h" +#include "gnutls_random.h" +#include "auth_srp_passwd.h" +#include "gnutls_srp.h" +#include "gnutls_errors.h" +#include "debug.h" + +typedef struct { + uint32 S[4][256], P[18]; +} blf_ctx; + +#define BF_N 16 + +#define F(bc, x) ( ((bc->S[0][(x >> 24) & 0xff] + bc->S[1][(x >> 16) & 0xff]) ^ bc->S[2][(x >> 8) & 0xff]) + bc->S[3][x & 0xff] ) + +/* x should be a 64 bit integer */ +static void _blf_encrypt(blf_ctx * c, uint8 * x) +{ + uint32 Xl; + uint32 Xr, temp; + short i; + + Xl = x[0] << 24 | x[1] << 16 | x[2] << 8 | x[3]; + Xr = x[4] << 24 | x[5] << 16 | x[6] << 8 | x[7]; + + for (i = 0; i < BF_N; ++i) { + Xl ^= c->P[i]; + Xr ^= F(c, Xl); + + temp = Xl; + Xl = Xr; + Xr = temp; + } + + temp = Xl; + Xl = Xr; + Xr = temp; + + Xr ^= c->P[BF_N]; + Xl ^= c->P[BF_N + 1]; + + x[0] = (Xl >> 24) & 0xff; + x[1] = (Xl >> 16) & 0xff; + x[2] = (Xl >> 8) & 0xff; + x[3] = (Xl) & 0xff; + x[4] = (Xr >> 24) & 0xff; + x[5] = (Xr >> 16) & 0xff; + x[6] = (Xr >> 8) & 0xff; + x[7] = (Xr) & 0xff; +} + +/* x should be a 64 bit integer */ +static void enblf_noswap(blf_ctx * c, uint32 * x) +{ /* Used internally */ + uint32 Xl; + uint32 Xr, temp; + short i; + + Xl = x[0]; + Xr = x[1]; + + for (i = 0; i < BF_N; ++i) { + Xl ^= c->P[i]; + Xr ^= F(c, Xl); + + temp = Xl; + Xl = Xr; + Xr = temp; + } + + temp = Xl; + Xl = Xr; + Xr = temp; + + Xr ^= c->P[BF_N]; + Xl ^= c->P[BF_N + 1]; + + x[0] = Xl; + x[1] = Xr; +} + + +/* salt is an 128 bit integer */ +static short initialize_blowfish(blf_ctx * c) +{ + short i; + + uint32 ks0[] = { + 0xd1310ba6UL, 0x98dfb5acUL, 0x2ffd72dbUL, 0xd01adfb7UL, + 0xb8e1afedUL, 0x6a267e96UL, + 0xba7c9045UL, 0xf12c7f99UL, 0x24a19947UL, 0xb3916cf7UL, + 0x0801f2e2UL, 0x858efc16UL, + 0x636920d8UL, 0x71574e69UL, 0xa458fea3UL, 0xf4933d7eUL, + 0x0d95748fUL, 0x728eb658UL, + 0x718bcd58UL, 0x82154aeeUL, 0x7b54a41dUL, 0xc25a59b5UL, + 0x9c30d539UL, 0x2af26013UL, + 0xc5d1b023UL, 0x286085f0UL, 0xca417918UL, 0xb8db38efUL, + 0x8e79dcb0UL, 0x603a180eUL, + 0x6c9e0e8bUL, 0xb01e8a3eUL, 0xd71577c1UL, 0xbd314b27UL, + 0x78af2fdaUL, 0x55605c60UL, + 0xe65525f3UL, 0xaa55ab94UL, 0x57489862UL, 0x63e81440UL, + 0x55ca396aUL, 0x2aab10b6UL, + 0xb4cc5c34UL, 0x1141e8ceUL, 0xa15486afUL, 0x7c72e993UL, + 0xb3ee1411UL, 0x636fbc2aUL, + 0x2ba9c55dUL, 0x741831f6UL, 0xce5c3e16UL, 0x9b87931eUL, + 0xafd6ba33UL, 0x6c24cf5cUL, + 0x7a325381UL, 0x28958677UL, 0x3b8f4898UL, 0x6b4bb9afUL, + 0xc4bfe81bUL, 0x66282193UL, + 0x61d809ccUL, 0xfb21a991UL, 0x487cac60UL, 0x5dec8032UL, + 0xef845d5dUL, 0xe98575b1UL, + 0xdc262302UL, 0xeb651b88UL, 0x23893e81UL, 0xd396acc5UL, + 0x0f6d6ff3UL, 0x83f44239UL, + 0x2e0b4482UL, 0xa4842004UL, 0x69c8f04aUL, 0x9e1f9b5eUL, + 0x21c66842UL, 0xf6e96c9aUL, + 0x670c9c61UL, 0xabd388f0UL, 0x6a51a0d2UL, 0xd8542f68UL, + 0x960fa728UL, 0xab5133a3UL, + 0x6eef0b6cUL, 0x137a3be4UL, 0xba3bf050UL, 0x7efb2a98UL, + 0xa1f1651dUL, 0x39af0176UL, + 0x66ca593eUL, 0x82430e88UL, 0x8cee8619UL, 0x456f9fb4UL, + 0x7d84a5c3UL, 0x3b8b5ebeUL, + 0xe06f75d8UL, 0x85c12073UL, 0x401a449fUL, 0x56c16aa6UL, + 0x4ed3aa62UL, 0x363f7706UL, + 0x1bfedf72UL, 0x429b023dUL, 0x37d0d724UL, 0xd00a1248UL, + 0xdb0fead3UL, 0x49f1c09bUL, + 0x075372c9UL, 0x80991b7bUL, 0x25d479d8UL, 0xf6e8def7UL, + 0xe3fe501aUL, 0xb6794c3bUL, + 0x976ce0bdUL, 0x04c006baUL, 0xc1a94fb6UL, 0x409f60c4UL, + 0x5e5c9ec2UL, 0x196a2463UL, + 0x68fb6fafUL, 0x3e6c53b5UL, 0x1339b2ebUL, 0x3b52ec6fUL, + 0x6dfc511fUL, 0x9b30952cUL, + 0xcc814544UL, 0xaf5ebd09UL, 0xbee3d004UL, 0xde334afdUL, + 0x660f2807UL, 0x192e4bb3UL, + 0xc0cba857UL, 0x45c8740fUL, 0xd20b5f39UL, 0xb9d3fbdbUL, + 0x5579c0bdUL, 0x1a60320aUL, + 0xd6a100c6UL, 0x402c7279UL, 0x679f25feUL, 0xfb1fa3ccUL, + 0x8ea5e9f8UL, 0xdb3222f8UL, + 0x3c7516dfUL, 0xfd616b15UL, 0x2f501ec8UL, 0xad0552abUL, + 0x323db5faUL, 0xfd238760UL, + 0x53317b48UL, 0x3e00df82UL, 0x9e5c57bbUL, 0xca6f8ca0UL, + 0x1a87562eUL, 0xdf1769dbUL, + 0xd542a8f6UL, 0x287effc3UL, 0xac6732c6UL, 0x8c4f5573UL, + 0x695b27b0UL, 0xbbca58c8UL, + 0xe1ffa35dUL, 0xb8f011a0UL, 0x10fa3d98UL, 0xfd2183b8UL, + 0x4afcb56cUL, 0x2dd1d35bUL, + 0x9a53e479UL, 0xb6f84565UL, 0xd28e49bcUL, 0x4bfb9790UL, + 0xe1ddf2daUL, 0xa4cb7e33UL, + 0x62fb1341UL, 0xcee4c6e8UL, 0xef20cadaUL, 0x36774c01UL, + 0xd07e9efeUL, 0x2bf11fb4UL, + 0x95dbda4dUL, 0xae909198UL, 0xeaad8e71UL, 0x6b93d5a0UL, + 0xd08ed1d0UL, 0xafc725e0UL, + 0x8e3c5b2fUL, 0x8e7594b7UL, 0x8ff6e2fbUL, 0xf2122b64UL, + 0x8888b812UL, 0x900df01cUL, + 0x4fad5ea0UL, 0x688fc31cUL, 0xd1cff191UL, 0xb3a8c1adUL, + 0x2f2f2218UL, 0xbe0e1777UL, + 0xea752dfeUL, 0x8b021fa1UL, 0xe5a0cc0fUL, 0xb56f74e8UL, + 0x18acf3d6UL, 0xce89e299UL, + 0xb4a84fe0UL, 0xfd13e0b7UL, 0x7cc43b81UL, 0xd2ada8d9UL, + 0x165fa266UL, 0x80957705UL, + 0x93cc7314UL, 0x211a1477UL, 0xe6ad2065UL, 0x77b5fa86UL, + 0xc75442f5UL, 0xfb9d35cfUL, + 0xebcdaf0cUL, 0x7b3e89a0UL, 0xd6411bd3UL, 0xae1e7e49UL, + 0x00250e2dUL, 0x2071b35eUL, + 0x226800bbUL, 0x57b8e0afUL, 0x2464369bUL, 0xf009b91eUL, + 0x5563911dUL, 0x59dfa6aaUL, + 0x78c14389UL, 0xd95a537fUL, 0x207d5ba2UL, 0x02e5b9c5UL, + 0x83260376UL, 0x6295cfa9UL, + 0x11c81968UL, 0x4e734a41UL, 0xb3472dcaUL, 0x7b14a94aUL, + 0x1b510052UL, 0x9a532915UL, + 0xd60f573fUL, 0xbc9bc6e4UL, 0x2b60a476UL, 0x81e67400UL, + 0x08ba6fb5UL, 0x571be91fUL, + 0xf296ec6bUL, 0x2a0dd915UL, 0xb6636521UL, 0xe7b9f9b6UL, + 0xff34052eUL, 0xc5855664UL, + 0x53b02d5dUL, 0xa99f8fa1UL, 0x08ba4799UL, 0x6e85076aUL + }; + + uint32 ks1[] = { + 0x4b7a70e9UL, 0xb5b32944UL, 0xdb75092eUL, 0xc4192623UL, + 0xad6ea6b0UL, 0x49a7df7dUL, + 0x9cee60b8UL, 0x8fedb266UL, 0xecaa8c71UL, 0x699a17ffUL, + 0x5664526cUL, 0xc2b19ee1UL, + 0x193602a5UL, 0x75094c29UL, 0xa0591340UL, 0xe4183a3eUL, + 0x3f54989aUL, 0x5b429d65UL, + 0x6b8fe4d6UL, 0x99f73fd6UL, 0xa1d29c07UL, 0xefe830f5UL, + 0x4d2d38e6UL, 0xf0255dc1UL, + 0x4cdd2086UL, 0x8470eb26UL, 0x6382e9c6UL, 0x021ecc5eUL, + 0x09686b3fUL, 0x3ebaefc9UL, + 0x3c971814UL, 0x6b6a70a1UL, 0x687f3584UL, 0x52a0e286UL, + 0xb79c5305UL, 0xaa500737UL, + 0x3e07841cUL, 0x7fdeae5cUL, 0x8e7d44ecUL, 0x5716f2b8UL, + 0xb03ada37UL, 0xf0500c0dUL, + 0xf01c1f04UL, 0x0200b3ffUL, 0xae0cf51aUL, 0x3cb574b2UL, + 0x25837a58UL, 0xdc0921bdUL, + 0xd19113f9UL, 0x7ca92ff6UL, 0x94324773UL, 0x22f54701UL, + 0x3ae5e581UL, 0x37c2dadcUL, + 0xc8b57634UL, 0x9af3dda7UL, 0xa9446146UL, 0x0fd0030eUL, + 0xecc8c73eUL, 0xa4751e41UL, + 0xe238cd99UL, 0x3bea0e2fUL, 0x3280bba1UL, 0x183eb331UL, + 0x4e548b38UL, 0x4f6db908UL, + 0x6f420d03UL, 0xf60a04bfUL, 0x2cb81290UL, 0x24977c79UL, + 0x5679b072UL, 0xbcaf89afUL, + 0xde9a771fUL, 0xd9930810UL, 0xb38bae12UL, 0xdccf3f2eUL, + 0x5512721fUL, 0x2e6b7124UL, + 0x501adde6UL, 0x9f84cd87UL, 0x7a584718UL, 0x7408da17UL, + 0xbc9f9abcUL, 0xe94b7d8cUL, + 0xec7aec3aUL, 0xdb851dfaUL, 0x63094366UL, 0xc464c3d2UL, + 0xef1c1847UL, 0x3215d908UL, + 0xdd433b37UL, 0x24c2ba16UL, 0x12a14d43UL, 0x2a65c451UL, + 0x50940002UL, 0x133ae4ddUL, + 0x71dff89eUL, 0x10314e55UL, 0x81ac77d6UL, 0x5f11199bUL, + 0x043556f1UL, 0xd7a3c76bUL, + 0x3c11183bUL, 0x5924a509UL, 0xf28fe6edUL, 0x97f1fbfaUL, + 0x9ebabf2cUL, 0x1e153c6eUL, + 0x86e34570UL, 0xeae96fb1UL, 0x860e5e0aUL, 0x5a3e2ab3UL, + 0x771fe71cUL, 0x4e3d06faUL, + 0x2965dcb9UL, 0x99e71d0fUL, 0x803e89d6UL, 0x5266c825UL, + 0x2e4cc978UL, 0x9c10b36aUL, + 0xc6150ebaUL, 0x94e2ea78UL, 0xa5fc3c53UL, 0x1e0a2df4UL, + 0xf2f74ea7UL, 0x361d2b3dUL, + 0x1939260fUL, 0x19c27960UL, 0x5223a708UL, 0xf71312b6UL, + 0xebadfe6eUL, 0xeac31f66UL, + 0xe3bc4595UL, 0xa67bc883UL, 0xb17f37d1UL, 0x018cff28UL, + 0xc332ddefUL, 0xbe6c5aa5UL, + 0x65582185UL, 0x68ab9802UL, 0xeecea50fUL, 0xdb2f953bUL, + 0x2aef7dadUL, 0x5b6e2f84UL, + 0x1521b628UL, 0x29076170UL, 0xecdd4775UL, 0x619f1510UL, + 0x13cca830UL, 0xeb61bd96UL, + 0x0334fe1eUL, 0xaa0363cfUL, 0xb5735c90UL, 0x4c70a239UL, + 0xd59e9e0bUL, 0xcbaade14UL, + 0xeecc86bcUL, 0x60622ca7UL, 0x9cab5cabUL, 0xb2f3846eUL, + 0x648b1eafUL, 0x19bdf0caUL, + 0xa02369b9UL, 0x655abb50UL, 0x40685a32UL, 0x3c2ab4b3UL, + 0x319ee9d5UL, 0xc021b8f7UL, + 0x9b540b19UL, 0x875fa099UL, 0x95f7997eUL, 0x623d7da8UL, + 0xf837889aUL, 0x97e32d77UL, + 0x11ed935fUL, 0x16681281UL, 0x0e358829UL, 0xc7e61fd6UL, + 0x96dedfa1UL, 0x7858ba99UL, + 0x57f584a5UL, 0x1b227263UL, 0x9b83c3ffUL, 0x1ac24696UL, + 0xcdb30aebUL, 0x532e3054UL, + 0x8fd948e4UL, 0x6dbc3128UL, 0x58ebf2efUL, 0x34c6ffeaUL, + 0xfe28ed61UL, 0xee7c3c73UL, + 0x5d4a14d9UL, 0xe864b7e3UL, 0x42105d14UL, 0x203e13e0UL, + 0x45eee2b6UL, 0xa3aaabeaUL, + 0xdb6c4f15UL, 0xfacb4fd0UL, 0xc742f442UL, 0xef6abbb5UL, + 0x654f3b1dUL, 0x41cd2105UL, + 0xd81e799eUL, 0x86854dc7UL, 0xe44b476aUL, 0x3d816250UL, + 0xcf62a1f2UL, 0x5b8d2646UL, + 0xfc8883a0UL, 0xc1c7b6a3UL, 0x7f1524c3UL, 0x69cb7492UL, + 0x47848a0bUL, 0x5692b285UL, + 0x095bbf00UL, 0xad19489dUL, 0x1462b174UL, 0x23820e00UL, + 0x58428d2aUL, 0x0c55f5eaUL, + 0x1dadf43eUL, 0x233f7061UL, 0x3372f092UL, 0x8d937e41UL, + 0xd65fecf1UL, 0x6c223bdbUL, + 0x7cde3759UL, 0xcbee7460UL, 0x4085f2a7UL, 0xce77326eUL, + 0xa6078084UL, 0x19f8509eUL, + 0xe8efd855UL, 0x61d99735UL, 0xa969a7aaUL, 0xc50c06c2UL, + 0x5a04abfcUL, 0x800bcadcUL, + 0x9e447a2eUL, 0xc3453484UL, 0xfdd56705UL, 0x0e1e9ec9UL, + 0xdb73dbd3UL, 0x105588cdUL, + 0x675fda79UL, 0xe3674340UL, 0xc5c43465UL, 0x713e38d8UL, + 0x3d28f89eUL, 0xf16dff20UL, + 0x153e21e7UL, 0x8fb03d4aUL, 0xe6e39f2bUL, 0xdb83adf7UL + }; + + uint32 ks2[] = { + 0xe93d5a68UL, 0x948140f7UL, 0xf64c261cUL, 0x94692934UL, + 0x411520f7UL, 0x7602d4f7UL, + 0xbcf46b2eUL, 0xd4a20068UL, 0xd4082471UL, 0x3320f46aUL, + 0x43b7d4b7UL, 0x500061afUL, + 0x1e39f62eUL, 0x97244546UL, 0x14214f74UL, 0xbf8b8840UL, + 0x4d95fc1dUL, 0x96b591afUL, + 0x70f4ddd3UL, 0x66a02f45UL, 0xbfbc09ecUL, 0x03bd9785UL, + 0x7fac6dd0UL, 0x31cb8504UL, + 0x96eb27b3UL, 0x55fd3941UL, 0xda2547e6UL, 0xabca0a9aUL, + 0x28507825UL, 0x530429f4UL, + 0x0a2c86daUL, 0xe9b66dfbUL, 0x68dc1462UL, 0xd7486900UL, + 0x680ec0a4UL, 0x27a18deeUL, + 0x4f3ffea2UL, 0xe887ad8cUL, 0xb58ce006UL, 0x7af4d6b6UL, + 0xaace1e7cUL, 0xd3375fecUL, + 0xce78a399UL, 0x406b2a42UL, 0x20fe9e35UL, 0xd9f385b9UL, + 0xee39d7abUL, 0x3b124e8bUL, + 0x1dc9faf7UL, 0x4b6d1856UL, 0x26a36631UL, 0xeae397b2UL, + 0x3a6efa74UL, 0xdd5b4332UL, + 0x6841e7f7UL, 0xca7820fbUL, 0xfb0af54eUL, 0xd8feb397UL, + 0x454056acUL, 0xba489527UL, + 0x55533a3aUL, 0x20838d87UL, 0xfe6ba9b7UL, 0xd096954bUL, + 0x55a867bcUL, 0xa1159a58UL, + 0xcca92963UL, 0x99e1db33UL, 0xa62a4a56UL, 0x3f3125f9UL, + 0x5ef47e1cUL, 0x9029317cUL, + 0xfdf8e802UL, 0x04272f70UL, 0x80bb155cUL, 0x05282ce3UL, + 0x95c11548UL, 0xe4c66d22UL, + 0x48c1133fUL, 0xc70f86dcUL, 0x07f9c9eeUL, 0x41041f0fUL, + 0x404779a4UL, 0x5d886e17UL, + 0x325f51ebUL, 0xd59bc0d1UL, 0xf2bcc18fUL, 0x41113564UL, + 0x257b7834UL, 0x602a9c60UL, + 0xdff8e8a3UL, 0x1f636c1bUL, 0x0e12b4c2UL, 0x02e1329eUL, + 0xaf664fd1UL, 0xcad18115UL, + 0x6b2395e0UL, 0x333e92e1UL, 0x3b240b62UL, 0xeebeb922UL, + 0x85b2a20eUL, 0xe6ba0d99UL, + 0xde720c8cUL, 0x2da2f728UL, 0xd0127845UL, 0x95b794fdUL, + 0x647d0862UL, 0xe7ccf5f0UL, + 0x5449a36fUL, 0x877d48faUL, 0xc39dfd27UL, 0xf33e8d1eUL, + 0x0a476341UL, 0x992eff74UL, + 0x3a6f6eabUL, 0xf4f8fd37UL, 0xa812dc60UL, 0xa1ebddf8UL, + 0x991be14cUL, 0xdb6e6b0dUL, + 0xc67b5510UL, 0x6d672c37UL, 0x2765d43bUL, 0xdcd0e804UL, + 0xf1290dc7UL, 0xcc00ffa3UL, + 0xb5390f92UL, 0x690fed0bUL, 0x667b9ffbUL, 0xcedb7d9cUL, + 0xa091cf0bUL, 0xd9155ea3UL, + 0xbb132f88UL, 0x515bad24UL, 0x7b9479bfUL, 0x763bd6ebUL, + 0x37392eb3UL, 0xcc115979UL, + 0x8026e297UL, 0xf42e312dUL, 0x6842ada7UL, 0xc66a2b3bUL, + 0x12754cccUL, 0x782ef11cUL, + 0x6a124237UL, 0xb79251e7UL, 0x06a1bbe6UL, 0x4bfb6350UL, + 0x1a6b1018UL, 0x11caedfaUL, + 0x3d25bdd8UL, 0xe2e1c3c9UL, 0x44421659UL, 0x0a121386UL, + 0xd90cec6eUL, 0xd5abea2aUL, + 0x64af674eUL, 0xda86a85fUL, 0xbebfe988UL, 0x64e4c3feUL, + 0x9dbc8057UL, 0xf0f7c086UL, + 0x60787bf8UL, 0x6003604dUL, 0xd1fd8346UL, 0xf6381fb0UL, + 0x7745ae04UL, 0xd736fcccUL, + 0x83426b33UL, 0xf01eab71UL, 0xb0804187UL, 0x3c005e5fUL, + 0x77a057beUL, 0xbde8ae24UL, + 0x55464299UL, 0xbf582e61UL, 0x4e58f48fUL, 0xf2ddfda2UL, + 0xf474ef38UL, 0x8789bdc2UL, + 0x5366f9c3UL, 0xc8b38e74UL, 0xb475f255UL, 0x46fcd9b9UL, + 0x7aeb2661UL, 0x8b1ddf84UL, + 0x846a0e79UL, 0x915f95e2UL, 0x466e598eUL, 0x20b45770UL, + 0x8cd55591UL, 0xc902de4cUL, + 0xb90bace1UL, 0xbb8205d0UL, 0x11a86248UL, 0x7574a99eUL, + 0xb77f19b6UL, 0xe0a9dc09UL, + 0x662d09a1UL, 0xc4324633UL, 0xe85a1f02UL, 0x09f0be8cUL, + 0x4a99a025UL, 0x1d6efe10UL, + 0x1ab93d1dUL, 0x0ba5a4dfUL, 0xa186f20fUL, 0x2868f169UL, + 0xdcb7da83UL, 0x573906feUL, + 0xa1e2ce9bUL, 0x4fcd7f52UL, 0x50115e01UL, 0xa70683faUL, + 0xa002b5c4UL, 0x0de6d027UL, + 0x9af88c27UL, 0x773f8641UL, 0xc3604c06UL, 0x61a806b5UL, + 0xf0177a28UL, 0xc0f586e0UL, + 0x006058aaUL, 0x30dc7d62UL, 0x11e69ed7UL, 0x2338ea63UL, + 0x53c2dd94UL, 0xc2c21634UL, + 0xbbcbee56UL, 0x90bcb6deUL, 0xebfc7da1UL, 0xce591d76UL, + 0x6f05e409UL, 0x4b7c0188UL, + 0x39720a3dUL, 0x7c927c24UL, 0x86e3725fUL, 0x724d9db9UL, + 0x1ac15bb4UL, 0xd39eb8fcUL, + 0xed545578UL, 0x08fca5b5UL, 0xd83d7cd3UL, 0x4dad0fc4UL, + 0x1e50ef5eUL, 0xb161e6f8UL, + 0xa28514d9UL, 0x6c51133cUL, 0x6fd5c7e7UL, 0x56e14ec4UL, + 0x362abfceUL, 0xddc6c837UL, + 0xd79a3234UL, 0x92638212UL, 0x670efa8eUL, 0x406000e0UL + }; + + uint32 ks3[] = { + 0x3a39ce37UL, 0xd3faf5cfUL, 0xabc27737UL, 0x5ac52d1bUL, + 0x5cb0679eUL, 0x4fa33742UL, + 0xd3822740UL, 0x99bc9bbeUL, 0xd5118e9dUL, 0xbf0f7315UL, + 0xd62d1c7eUL, 0xc700c47bUL, + 0xb78c1b6bUL, 0x21a19045UL, 0xb26eb1beUL, 0x6a366eb4UL, + 0x5748ab2fUL, 0xbc946e79UL, + 0xc6a376d2UL, 0x6549c2c8UL, 0x530ff8eeUL, 0x468dde7dUL, + 0xd5730a1dUL, 0x4cd04dc6UL, + 0x2939bbdbUL, 0xa9ba4650UL, 0xac9526e8UL, 0xbe5ee304UL, + 0xa1fad5f0UL, 0x6a2d519aUL, + 0x63ef8ce2UL, 0x9a86ee22UL, 0xc089c2b8UL, 0x43242ef6UL, + 0xa51e03aaUL, 0x9cf2d0a4UL, + 0x83c061baUL, 0x9be96a4dUL, 0x8fe51550UL, 0xba645bd6UL, + 0x2826a2f9UL, 0xa73a3ae1UL, + 0x4ba99586UL, 0xef5562e9UL, 0xc72fefd3UL, 0xf752f7daUL, + 0x3f046f69UL, 0x77fa0a59UL, + 0x80e4a915UL, 0x87b08601UL, 0x9b09e6adUL, 0x3b3ee593UL, + 0xe990fd5aUL, 0x9e34d797UL, + 0x2cf0b7d9UL, 0x022b8b51UL, 0x96d5ac3aUL, 0x017da67dUL, + 0xd1cf3ed6UL, 0x7c7d2d28UL, + 0x1f9f25cfUL, 0xadf2b89bUL, 0x5ad6b472UL, 0x5a88f54cUL, + 0xe029ac71UL, 0xe019a5e6UL, + 0x47b0acfdUL, 0xed93fa9bUL, 0xe8d3c48dUL, 0x283b57ccUL, + 0xf8d56629UL, 0x79132e28UL, + 0x785f0191UL, 0xed756055UL, 0xf7960e44UL, 0xe3d35e8cUL, + 0x15056dd4UL, 0x88f46dbaUL, + 0x03a16125UL, 0x0564f0bdUL, 0xc3eb9e15UL, 0x3c9057a2UL, + 0x97271aecUL, 0xa93a072aUL, + 0x1b3f6d9bUL, 0x1e6321f5UL, 0xf59c66fbUL, 0x26dcf319UL, + 0x7533d928UL, 0xb155fdf5UL, + 0x03563482UL, 0x8aba3cbbUL, 0x28517711UL, 0xc20ad9f8UL, + 0xabcc5167UL, 0xccad925fUL, + 0x4de81751UL, 0x3830dc8eUL, 0x379d5862UL, 0x9320f991UL, + 0xea7a90c2UL, 0xfb3e7bceUL, + 0x5121ce64UL, 0x774fbe32UL, 0xa8b6e37eUL, 0xc3293d46UL, + 0x48de5369UL, 0x6413e680UL, + 0xa2ae0810UL, 0xdd6db224UL, 0x69852dfdUL, 0x09072166UL, + 0xb39a460aUL, 0x6445c0ddUL, + 0x586cdecfUL, 0x1c20c8aeUL, 0x5bbef7ddUL, 0x1b588d40UL, + 0xccd2017fUL, 0x6bb4e3bbUL, + 0xdda26a7eUL, 0x3a59ff45UL, 0x3e350a44UL, 0xbcb4cdd5UL, + 0x72eacea8UL, 0xfa6484bbUL, + 0x8d6612aeUL, 0xbf3c6f47UL, 0xd29be463UL, 0x542f5d9eUL, + 0xaec2771bUL, 0xf64e6370UL, + 0x740e0d8dUL, 0xe75b1357UL, 0xf8721671UL, 0xaf537d5dUL, + 0x4040cb08UL, 0x4eb4e2ccUL, + 0x34d2466aUL, 0x0115af84UL, 0xe1b00428UL, 0x95983a1dUL, + 0x06b89fb4UL, 0xce6ea048UL, + 0x6f3f3b82UL, 0x3520ab82UL, 0x011a1d4bUL, 0x277227f8UL, + 0x611560b1UL, 0xe7933fdcUL, + 0xbb3a792bUL, 0x344525bdUL, 0xa08839e1UL, 0x51ce794bUL, + 0x2f32c9b7UL, 0xa01fbac9UL, + 0xe01cc87eUL, 0xbcc7d1f6UL, 0xcf0111c3UL, 0xa1e8aac7UL, + 0x1a908749UL, 0xd44fbd9aUL, + 0xd0dadecbUL, 0xd50ada38UL, 0x0339c32aUL, 0xc6913667UL, + 0x8df9317cUL, 0xe0b12b4fUL, + 0xf79e59b7UL, 0x43f5bb3aUL, 0xf2d519ffUL, 0x27d9459cUL, + 0xbf97222cUL, 0x15e6fc2aUL, + 0x0f91fc71UL, 0x9b941525UL, 0xfae59361UL, 0xceb69cebUL, + 0xc2a86459UL, 0x12baa8d1UL, + 0xb6c1075eUL, 0xe3056a0cUL, 0x10d25065UL, 0xcb03a442UL, + 0xe0ec6e0eUL, 0x1698db3bUL, + 0x4c98a0beUL, 0x3278e964UL, 0x9f1f9532UL, 0xe0d392dfUL, + 0xd3a0342bUL, 0x8971f21eUL, + 0x1b0a7441UL, 0x4ba3348cUL, 0xc5be7120UL, 0xc37632d8UL, + 0xdf359f8dUL, 0x9b992f2eUL, + 0xe60b6f47UL, 0x0fe3f11dUL, 0xe54cda54UL, 0x1edad891UL, + 0xce6279cfUL, 0xcd3e7e6fUL, + 0x1618b166UL, 0xfd2c1d05UL, 0x848fd2c5UL, 0xf6fb2299UL, + 0xf523f357UL, 0xa6327623UL, + 0x93a83531UL, 0x56cccd02UL, 0xacf08162UL, 0x5a75ebb5UL, + 0x6e163697UL, 0x88d273ccUL, + 0xde966292UL, 0x81b949d0UL, 0x4c50901bUL, 0x71c65614UL, + 0xe6c6c7bdUL, 0x327a140aUL, + 0x45e1d006UL, 0xc3f27b9aUL, 0xc9aa53fdUL, 0x62a80f00UL, + 0xbb25bfe2UL, 0x35bdd2f6UL, + 0x71126905UL, 0xb2040222UL, 0xb6cbcf7cUL, 0xcd769c2bUL, + 0x53113ec0UL, 0x1640e3d3UL, + 0x38abbd60UL, 0x2547adf0UL, 0xba38209cUL, 0xf746ce76UL, + 0x77afa1c5UL, 0x20756060UL, + 0x85cbfe4eUL, 0x8ae88dd8UL, 0x7aaaf9b0UL, 0x4cf9aa7eUL, + 0x1948c25cUL, 0x02fb8a8cUL, + 0x01c36ae4UL, 0xd6ebe1f9UL, 0x90d4f869UL, 0xa65cdea0UL, + 0x3f09252dUL, 0xc208e69fUL, + 0xb74e6132UL, 0xce77e25bUL, 0x578fdfe3UL, 0x3ac372e6UL + }; + + + uint32 pi[] = { + 0x243f6a88UL, 0x85a308d3UL, 0x13198a2eUL, 0x03707344UL, + 0xa4093822UL, 0x299f31d0UL, + 0x082efa98UL, 0xec4e6c89UL, 0x452821e6UL, 0x38d01377UL, + 0xbe5466cfUL, 0x34e90c6cUL, + 0xc0ac29b7UL, 0xc97c50ddUL, 0x3f84d5b5UL, 0xb5470917UL, + 0x9216d5d9UL, 0x8979fb1bUL + }; + + +/* Initialize s-boxes without file read. */ + for (i = 0; i < 256; i++) { + c->S[0][i] = ks0[i]; + c->S[1][i] = ks1[i]; + c->S[2][i] = ks2[i]; + c->S[3][i] = ks3[i]; + } + +/* P-boxes */ + for (i = 0; i < 18; i++) { + c->P[i] = pi[i]; + } + return 0; +} + +static short _blf_ExpandKey(blf_ctx * c, const uint8 * key, short keybytes, + const uint8 * bsalt) +{ + short i, j; + int k; + uint32 data, temp[2]; + uint32 wsalt[4]; + + if (bsalt != NULL) { + wsalt[0] = 0x00000000; + wsalt[1] = 0x00000000; + wsalt[2] = 0x00000000; + wsalt[3] = 0x00000000; + for (i = 0; i < 4; i++) { + wsalt[0] = (wsalt[0] << 8) | bsalt[i]; + wsalt[1] = (wsalt[1] << 8) | bsalt[i + 4]; + wsalt[2] = (wsalt[2] << 8) | bsalt[i + 8]; + wsalt[3] = (wsalt[3] << 8) | bsalt[i + 12]; + } + } + + temp[0] = temp[1] = 0x00000000; + + j = 0; + /* Step 1: XOR the Pbox with the key */ + for (i = 0; i < BF_N + 2; i++) { + data = 0x00000000; + data = (data << 8) | key[(j) % keybytes]; + data = (data << 8) | key[(j + 1) % keybytes]; + data = (data << 8) | key[(j + 2) % keybytes]; + data = (data << 8) | key[(j + 3) % keybytes]; + + c->P[i] ^= data; + j = (j + 4) % keybytes; + } + + k = 2; /* This should be 0 ??? */ + /* Step 2: Use the salt on Pbox */ + for (i = 0; i < BF_N + 2; i += 2) { + if (bsalt != NULL) { + temp[0] ^= wsalt[(k + 2) % 4]; + temp[1] ^= wsalt[(k + 3) % 4]; + k = (k + 2) % 4; + } + enblf_noswap(c, temp); + c->P[i] = temp[0]; + c->P[i + 1] = temp[1]; + } + + for (i = 0; i < 4; i++) { + for (j = 0; j < 256; j += 2) { + if (bsalt != NULL) { + temp[0] ^= wsalt[(k + 2) % 4]; + temp[1] ^= wsalt[(k + 3) % 4]; + k = (k + 2) % 4; + } + enblf_noswap(c, temp); + c->S[i][j] = temp[0]; + c->S[i][j + 1] = temp[1]; + + } + } + return 0; +} + + + + +static blf_ctx *_blf_init(uint8 * salt, const char *key, int key_len, + int cost) +{ + blf_ctx *state = gnutls_malloc(sizeof(blf_ctx)); + uint32 i, rcost; + + if (state==NULL) + return NULL; + + rcost = (uint32) 1 << cost; /* 2^cost */ + + initialize_blowfish(state); + _blf_ExpandKey(state, (uint8 *) key, key_len, salt); + for (i = 0; i < rcost; i++) { + /* these should have been in reverse order */ + _blf_ExpandKey(state, (uint8 *) key, key_len, NULL); + _blf_ExpandKey(state, salt, 16, NULL); + } + return state; +} + +static void _blf_deinit(blf_ctx * ctx) +{ + gnutls_free(ctx); +} +static const char magic[] = "$2$"; + +#define B64TEXT "OrpheanBeholderScryDoubt" + +char *crypt_bcrypt(const char* username, const char *passwd, const char *salt, GNUTLS_MPI g, GNUTLS_MPI n) +{ + unsigned char *sp; + blf_ctx *ctx; + unsigned char text[24]; + uint8 *csalt; + uint8 *rtext; + uint8 cost; + int i, salt_size = strlen(salt), len; + unsigned char *local_salt, *v; + int passwd_len, vsize, tmpsize; + opaque *tmp; + + /* copy username+null+B64TEXT to text */ + strncpy( text, username, sizeof(text)); + if ( ( sizeof(text)-strlen(username) - 1 ) > 0) + strncpy( &text[strlen(username)+1], B64TEXT, sizeof(text)-strlen(username)-1); + + passwd_len = strlen(passwd) + 1; /* we want the null also */ + if (passwd_len > 56) + passwd_len = 56; + + local_salt = gnutls_malloc(salt_size + 1); + if (local_salt==NULL) { + gnutls_assert(); + return NULL; + } + strcpy((char *) local_salt, salt); /* Flawfinder: ignore */ + + sp = index( local_salt, ':'); /* move to salt - after verifier */ + if (sp==NULL) { + gnutls_assert(); + return NULL; + } + sp++; + + len = (int)rindex(sp, ':'); + if (len==0) { /* no ':' was found */ + len = strlen(sp); + } else + len -= (int) sp; + + if (_gnutls_sbase64_decode(sp, len, &csalt) < 0) { + gnutls_assert(); + return NULL; + } + + cost = (int) csalt[0]; + ctx = _blf_init(&csalt[1], passwd, passwd_len, cost); + gnutls_free(csalt); + + if (ctx==NULL) { + return NULL; + } + + for (i = 0; i < 64; i++) { + _blf_encrypt(ctx, (uint8 *) text); + _blf_encrypt(ctx, (uint8 *) & text[8]); + _blf_encrypt(ctx, (uint8 *) & text[16]); + } + + /* v = g^x mod n */ + vsize = _gnutls_srp_gx(text, 8 * 3, &v, g, n); + if (vsize == -1 || v == NULL) { + gnutls_assert(); + return NULL; + } + + if (_gnutls_sbase64_encode(v, vsize, &rtext) < 0) { + gnutls_free(v); + gnutls_assert(); + return NULL; + } + gnutls_free(v); + + tmpsize = strlen(magic) + 3 + strlen(sp) + 1 + strlen(rtext) + 1; + tmp = + gnutls_malloc( tmpsize); + if (tmp==NULL) { + gnutls_assert(); + return NULL; + } + + sprintf(tmp, "%s%s:%s", magic, rtext, sp); /* Flawfinder: ignore */ + + gnutls_free(local_salt); + gnutls_free(rtext); + + _blf_deinit(ctx); + return tmp; +} + +/* cost is stored as the first byte in salt (thus < 255) which is + * just fine! + */ +char *crypt_bcrypt_wrapper(const char* username, const char *pass_new, int cost, GNUTLS_MPI g, GNUTLS_MPI n) +{ + opaque *result; + char *tcp; + uint8 rand[17]; + char *e = NULL; + int result_size; + + if (_gnutls_get_random(&rand[1], 17, GNUTLS_WEAK_RANDOM) < 0 ) { + gnutls_assert(); + return NULL; + } + /* cost should be <32 and >6 */ + if (cost >= 32) + cost = 31; + if (cost < 1) + cost = 1; + + rand[0] = (uint8) cost; + result_size = _gnutls_sbase64_encode( rand, 17, &result); + + if (result_size < 0) { + gnutls_assert(); + return NULL; + } + + tcp = gnutls_calloc(1, 1 + result_size + 1); + sprintf(tcp, ":%s", result); /* Flawfinder: ignore */ + + gnutls_free(result); + + + e = crypt_bcrypt(username, pass_new, (const char *) tcp, g, n); + gnutls_free(tcp); + + return e; +} + +#define BCRYPT_SIZE 24 +int _gnutls_calc_srp_bcrypt(const char* username, const char *passwd, opaque * salt, int salt_size, int* size, void* digest) +{ + blf_ctx *ctx; + opaque text[BCRYPT_SIZE]; + int passwd_len, i; + + strncpy( text, username, sizeof(text)); + if ( (sizeof(text)-strlen(username)-1) > 0) + strncpy( &text[strlen(username)+1], B64TEXT, sizeof(text)-strlen(username)-1); + + *size = sizeof(text); + + /* we need 16 + cost */ + if (salt_size < 17) return -1; + + passwd_len = strlen(passwd) + 1; /* we want the null also */ + if (passwd_len > 56) + passwd_len = 56; + + ctx = _blf_init(&salt[1], passwd, passwd_len, (int)(salt[0])); + if (ctx==NULL) { + return GNUTLS_E_MEMORY_ERROR; + } + + for (i = 0; i < 64; i++) { + _blf_encrypt(ctx, (uint8 *) text); + _blf_encrypt(ctx, (uint8 *) & text[8]); + _blf_encrypt(ctx, (uint8 *) & text[16]); + } + + _blf_deinit(ctx); + + memcpy( digest, text, BCRYPT_SIZE); + return 0; +} + +#endif /* ENABLE_SRP */ diff --git a/libextra/crypt_bcrypt.h b/libextra/crypt_bcrypt.h new file mode 100644 index 0000000000..00458a2e2b --- /dev/null +++ b/libextra/crypt_bcrypt.h @@ -0,0 +1,3 @@ +char * crypt_bcrypt (const char* username, const char *passwd, const char *salt, MPI g, MPI n); +char *crypt_bcrypt_wrapper(const char* username, const char *pass_new, int cost, MPI g, MPI n); +int _gnutls_calc_srp_bcrypt( const char* username, const char *passwd, opaque *salt, int salt_size, int* size, void* digest); diff --git a/libextra/crypt_srpsha1.c b/libextra/crypt_srpsha1.c new file mode 100644 index 0000000000..0dbc5ff8e8 --- /dev/null +++ b/libextra/crypt_srpsha1.c @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2001 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * GNUTLS 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 2 of the License, or + * (at your option) any later version. + * + * GNUTLS 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "gnutls_int.h" + +#ifdef ENABLE_SRP + +#include "gnutls_random.h" +#include "gnutls_hash_int.h" +#include "auth_srp_passwd.h" +#include "gnutls_srp.h" +#include + +/* x = SHA( | SHA( | ":" | )) */ + +static const char magic[] = ""; + +char *crypt_srpsha1(const char *username, const char *passwd, + const char *salt, GNUTLS_MPI g, GNUTLS_MPI n) +{ + unsigned char *sp, r1[MAX_HASH_SIZE]; + int salt_size = strlen(salt); + unsigned char *local_salt, *v; + int passwd_len; + GNUTLS_HASH_HANDLE h1; + int vsize, hash_len = _gnutls_hash_get_algo_len(GNUTLS_MAC_SHA); + opaque *tmp; + uint8 *rtext, *csalt; + int rsalt_size, len, tmpsize; + + passwd_len = strlen(passwd); /* we do not want the null */ + + h1 = _gnutls_hash_init(GNUTLS_MAC_SHA); + _gnutls_hash(h1, (char *) username, strlen(username)); + _gnutls_hash(h1, ":", 1); + _gnutls_hash(h1, (char *) passwd, passwd_len); + _gnutls_hash_deinit(h1, r1); + + + local_salt = gnutls_malloc(salt_size + 1); + if (local_salt==NULL) { + gnutls_assert(); + return NULL; + } + strcpy((char *) local_salt, salt); /* Flawfinder: ignore */ + + sp = index( local_salt, ':'); /* move to salt - after verifier */ + if (sp==NULL) { + gnutls_assert(); + gnutls_free( local_salt); + return NULL; + } + sp++; + + len = (int)rindex(sp, ':'); + if (len==0) { /* parse error */ + len = strlen(sp); + } else + len -= (int)sp; + + rsalt_size = _gnutls_sbase64_decode(sp, len, &csalt); + if (rsalt_size < 0) { + gnutls_assert(); + gnutls_free(local_salt); + return NULL; + } + + h1 = _gnutls_hash_init(GNUTLS_MAC_SHA); + if (h1==NULL) { + gnutls_assert(); + gnutls_free(local_salt); + return NULL; + } + _gnutls_hash(h1, csalt, rsalt_size); + gnutls_free(csalt); + + _gnutls_hash(h1, r1, hash_len); + + _gnutls_hash_deinit(h1, r1); + + /* v = g^x mod n */ + vsize = _gnutls_srp_gx(r1, hash_len, &v, g, n); + + if (vsize == -1 || v == NULL) { + gnutls_assert(); + gnutls_free(local_salt); + return NULL; + } + + if (_gnutls_sbase64_encode(v, vsize, &rtext) < 0) { + gnutls_free(v); + gnutls_free(local_salt); + gnutls_assert(); + return NULL; + } + gnutls_free(v); + + tmpsize = strlen(sp) + strlen(rtext) + strlen(magic) + 1 + 1; + tmp = + gnutls_malloc( tmpsize); + if (tmp==NULL) { + gnutls_assert(); + gnutls_free(local_salt); + return NULL; + } + sprintf(tmp, "%s%s:%s", magic, rtext, sp); /* Flawfinder: ignore */ + + gnutls_free(rtext); + gnutls_free(local_salt); + + return tmp; +} + +/* salt here is the salt size */ +char *crypt_srpsha1_wrapper(const char *username, const char *pass_new, + int salt, GNUTLS_MPI g, GNUTLS_MPI n) +{ + unsigned char *result; + char *tcp; + opaque *rand; + char *e = NULL; + int result_size; + + if (salt > 50 || salt <= 0) + return NULL; /* wow that's pretty long salt */ + + rand = gnutls_malloc(salt); + if (rand==NULL || _gnutls_get_random(rand, salt, GNUTLS_WEAK_RANDOM) < 0) { + gnutls_assert(); + return NULL; + } + + result_size = _gnutls_sbase64_encode(rand, salt, &result); + if (result_size < 0) { + gnutls_free(rand); + gnutls_assert(); + return NULL; + } + + tcp = gnutls_calloc(1, 1+ result_size + 1); + if (tcp==NULL) { + gnutls_assert(); + gnutls_free(rand); + return NULL; + } + sprintf(tcp, ":%s", result); /* Flawfinder: ignore */ + + gnutls_free(result); + gnutls_free(rand); + /* no longer need cleartext */ + + e = crypt_srpsha1(username, pass_new, (const char *) tcp, g, n); + gnutls_free(tcp); + + return e; +} + +#endif diff --git a/libextra/crypt_srpsha1.h b/libextra/crypt_srpsha1.h new file mode 100644 index 0000000000..bf0d55ebbe --- /dev/null +++ b/libextra/crypt_srpsha1.h @@ -0,0 +1,2 @@ +char * crypt_srpsha1(const char* username, const char *passwd, const char *salt, MPI g, MPI n); +char *crypt_srpsha1_wrapper(const char* username, const char *pass_new, int salt, MPI g, MPI n); diff --git a/libextra/ext_srp.c b/libextra/ext_srp.c new file mode 100644 index 0000000000..c04d5ced44 --- /dev/null +++ b/libextra/ext_srp.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2001,2002 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * GNUTLS 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 2 of the License, or + * (at your option) any later version. + * + * GNUTLS 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "gnutls_int.h" + +#ifdef ENABLE_SRP + +#include "gnutls_auth_int.h" +#include "auth_srp.h" +#include "gnutls_errors.h" +#include "gnutls_algorithms.h" + +int _gnutls_srp_recv_params( GNUTLS_STATE state, const opaque* data, int data_size) { + uint8 len; + + if (_gnutls_kx_priority( state, GNUTLS_KX_SRP) < 0) { + /* algorithm was not allowed in this state + */ + return 0; + } + + if (state->security_parameters.entity == GNUTLS_SERVER) { + if (data_size > 0) { + len = data[0]; + if (len > data_size) { + gnutls_assert(); + return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; + } + if ( sizeof( state->security_parameters.extensions.srp_username) <= len) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + memcpy( state->security_parameters.extensions.srp_username, &data[1], len); + state->security_parameters.extensions.srp_username[len]=0; /* null terminated */ + } + } else { /* client side reading server hello extensions */ + if (state->gnutls_internals.resumed==RESUME_FALSE) + return proc_srp_server_hello( state, data, data_size); + else /* we do not need to process this if + * we are resuming. + */ + return 0; + } + return 0; +} + +/* returns data_size or a negative number on failure + * data is allocated localy + */ +int _gnutls_srp_send_params( GNUTLS_STATE state, opaque* data, int data_size) { + uint8 len; + + if (_gnutls_kx_priority( state, GNUTLS_KX_SRP) < 0) { + /* algorithm was not allowed in this state + */ + return 0; + } + + /* this function sends the client extension data (username) */ + if (state->security_parameters.entity == GNUTLS_CLIENT) { + const GNUTLS_SRP_CLIENT_CREDENTIALS cred = _gnutls_get_cred( state->gnutls_key, GNUTLS_CRD_SRP, NULL); + + if (cred==NULL) return 0; + + if (cred->username!=NULL) { /* send username */ + len = strlen(cred->username); + if (data_size < len+1) { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + data[0] = len; + memcpy( &data[1], cred->username, len); + return len + 1; + } + } else { /* SERVER SIDE sending (g,n,s) */ + /* We only send the packet if we are NOT + * resuming AND we are using SRP + */ + + /* note that security parameters are not fully established + */ + if ( _gnutls_cipher_suite_get_kx_algo(state->security_parameters.current_cipher_suite) != GNUTLS_KX_SRP) + return 0; /* no data to send */ + + if (state->gnutls_internals.resumed==RESUME_FALSE) + return gen_srp_server_hello( state, data, data_size); + else + return 0; + } + return 0; +} + +#endif /* ENABLE_SRP */ diff --git a/libextra/ext_srp.h b/libextra/ext_srp.h new file mode 100644 index 0000000000..ae3158a693 --- /dev/null +++ b/libextra/ext_srp.h @@ -0,0 +1,6 @@ +#ifdef ENABLE_SRP + +int _gnutls_srp_recv_params( GNUTLS_STATE state, const opaque* data, int data_size); +int _gnutls_srp_send_params( GNUTLS_STATE state, opaque* data, int); + +#endif diff --git a/libextra/gnutls-extra.h b/libextra/gnutls-extra.h new file mode 100644 index 0000000000..e77c7bd6ff --- /dev/null +++ b/libextra/gnutls-extra.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2002 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * GNUTLS 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 2 of the License, or + * (at your option) any later version. + * + * GNUTLS 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/* Note the libgnutls-extra is not a standalone library. It requires + * to link also against libgnutls. + */ + +#ifndef GNUTLS_EXTRA_H +# define GNUTLS_EXTRA_H + +#include + +/* SRP */ + +typedef struct DSTRUCT* GNUTLS_SRP_SERVER_CREDENTIALS; +typedef struct DSTRUCT* GNUTLS_SRP_CLIENT_CREDENTIALS; + +void gnutls_srp_free_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS sc); +int gnutls_srp_allocate_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS *sc); +int gnutls_srp_set_client_cred( GNUTLS_SRP_CLIENT_CREDENTIALS res, char *username, char* password); + +void gnutls_srp_free_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS sc); +int gnutls_srp_allocate_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS *sc); +int gnutls_srp_set_server_cred_file( GNUTLS_SRP_SERVER_CREDENTIALS res, char *password_file, char* password_conf_file); + +const char* gnutls_srp_server_get_username( GNUTLS_STATE state); + +typedef int gnutls_srp_server_select_func(GNUTLS_STATE, char **, char**, int); + +void gnutls_srp_server_set_select_func( GNUTLS_STATE, gnutls_srp_server_select_func *); + +/* Openpgp certificate stuff */ +int gnutls_openpgp_extract_key_name( const gnutls_datum *cert, + int idx, + gnutls_openpgp_name *dn ); + +int gnutls_openpgp_extract_key_pk_algorithm(const gnutls_datum *cert, + int *r_bits); + +int gnutls_openpgp_extract_key_version( const gnutls_datum *cert ); + +time_t gnutls_openpgp_extract_key_creation_time( const gnutls_datum *cert ); +time_t gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert ); + +int gnutls_openpgp_verify_key( const gnutls_datum* keyring, + const gnutls_datum* key_list, + int key_list_length); + +int gnutls_certificate_set_openpgp_key_file( GNUTLS_CERTIFICATE_CREDENTIALS res, char *CERTFILE, char* KEYFILE); +int gnutls_certificate_set_openpgp_key_mem( GNUTLS_CERTIFICATE_CREDENTIALS res, + const gnutls_datum* CERT, const gnutls_datum* KEY); + +void gnutls_certificate_set_openpgp_keyserver(GNUTLS_CERTIFICATE_CREDENTIALS res, + char* keyserver, int port); + +void gnutls_certificate_set_openpgp_trustdb(GNUTLS_CERTIFICATE_CREDENTIALS res, + char* trustdb); + +int gnutls_certificate_set_openpgp_keyring_mem( GNUTLS_CERTIFICATE_CREDENTIALS res, + const char *data, size_t len); + +int gnutls_certificate_set_openpgp_keyring_file( GNUTLS_CERTIFICATE_CREDENTIALS res, const char *name); + +int gnutls_global_init_extra(void); + +#endif diff --git a/libextra/gnutls_extra.c b/libextra/gnutls_extra.c new file mode 100644 index 0000000000..a168d15552 --- /dev/null +++ b/libextra/gnutls_extra.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2002 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include + +extern gnutls_extension_entry _gnutls_extensions[]; +extern const int _gnutls_extensions_size; + +#define TOSTR(x) #x + +static int _gnutls_add_srp_extension(void) { +int i; + + /* find the last element */ + for(i=0;i<_gnutls_extensions_size;i++) { + if (_gnutls_extensions[i].name==NULL) break; + } + + if (_gnutls_extensions[i].name==NULL && (i < _gnutls_extensions_size-1)) { + _gnutls_extensions[i].name = TOSTR(GNUTLS_EXTENSION_SRP); + _gnutls_extensions[i].type = GNUTLS_EXTENSION_SRP; + _gnutls_extensions[i].gnutls_ext_func_recv = _gnutls_srp_recv_params; + _gnutls_extensions[i].gnutls_ext_func_send = _gnutls_srp_send_params; + + _gnutls_extensions[i+1].name = 0; + + return 0; /* ok */ + } + + return GNUTLS_E_MEMORY_ERROR; +} + +extern const int _gnutls_kx_algorithms_size; +extern gnutls_kx_algo_entry _gnutls_kx_algorithms[]; +extern MOD_AUTH_STRUCT srp_auth_struct; + +static int _gnutls_add_srp_auth_struct(void) { +int i; + + /* find the last element */ + for(i=0;i<_gnutls_kx_algorithms_size;i++) { + if (_gnutls_kx_algorithms[i].name==NULL) break; + } + + if (_gnutls_kx_algorithms[i].name==NULL && (i < _gnutls_kx_algorithms_size-1)) { + _gnutls_kx_algorithms[i].name = "SRP"; + _gnutls_kx_algorithms[i].algorithm = GNUTLS_KX_SRP; + _gnutls_kx_algorithms[i].auth_struct = &srp_auth_struct; + + _gnutls_kx_algorithms[i+1].name = 0; + + return 0; /* ok */ + } + + return GNUTLS_E_MEMORY_ERROR; +} + + +extern OPENPGP_KEY_CREATION_TIME_FUNC _E_gnutls_openpgp_extract_key_creation_time; +extern OPENPGP_KEY_EXPIRATION_TIME_FUNC _E_gnutls_openpgp_extract_key_expiration_time; +extern OPENPGP_VERIFY_KEY_FUNC _E_gnutls_openpgp_verify_key; +extern OPENPGP_CERT2GNUTLS_CERT _E_gnutls_openpgp_cert2gnutls_cert; +extern OPENPGP_FINGERPRINT _E_gnutls_openpgp_fingerprint; +extern OPENPGP_KEY_REQUEST _E_gnutls_openpgp_request_key; + +static void _gnutls_add_openpgp_functions(void) { + _E_gnutls_openpgp_verify_key = gnutls_openpgp_verify_key; + _E_gnutls_openpgp_extract_key_expiration_time = gnutls_openpgp_extract_key_expiration_time; + _E_gnutls_openpgp_extract_key_creation_time = gnutls_openpgp_extract_key_creation_time; + _E_gnutls_openpgp_fingerprint = gnutls_openpgp_fingerprint; + _E_gnutls_openpgp_request_key = _gnutls_openpgp_request_key; + _E_gnutls_openpgp_cert2gnutls_cert = _gnutls_openpgp_cert2gnutls_cert; + + return; +} + +static int _gnutls_init_extra = 0; + +/** + * gnutls_global_init_extra - This function initializes the global state of gnutls-extra + * + * This function initializes the global state of gnutls-extra library to defaults. + * Returns zero on success. + * + * Note that gnutls_global_init() has to be called before this function. + * If this function is not called then the gnutls-extra library will not + * be usable. + * + **/ +int gnutls_global_init_extra(void) { +int ret; + + _gnutls_init_extra++; + + if (_gnutls_init_extra!=1) { + return 0; + } + + ret = _gnutls_add_srp_auth_struct(); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + ret = _gnutls_add_srp_extension(); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + _gnutls_add_openpgp_functions(); + + return 0; +} diff --git a/libextra/gnutls_extra.h b/libextra/gnutls_extra.h new file mode 100644 index 0000000000..fba5882413 --- /dev/null +++ b/libextra/gnutls_extra.h @@ -0,0 +1,9 @@ +#include + +typedef int (*OPENPGP_VERIFY_KEY_FUNC)( const char *, + const gnutls_datum *, const gnutls_datum*, int); +typedef time_t (*OPENPGP_KEY_CREATION_TIME_FUNC)( const gnutls_datum*); +typedef time_t (*OPENPGP_KEY_EXPIRATION_TIME_FUNC)( const gnutls_datum*); +typedef int (*OPENPGP_KEY_REQUEST)(gnutls_datum*, const GNUTLS_CERTIFICATE_CREDENTIALS, opaque*,int); +typedef int (*OPENPGP_FINGERPRINT)(const gnutls_datum*, opaque*, size_t*); +typedef int (*OPENPGP_CERT2GNUTLS_CERT)(gnutls_cert*, gnutls_datum); diff --git a/libextra/gnutls_openpgp.c b/libextra/gnutls_openpgp.c new file mode 100644 index 0000000000..3f0eea3347 --- /dev/null +++ b/libextra/gnutls_openpgp.c @@ -0,0 +1,1702 @@ +/* + * Copyright (C) 2002 Timo Schulz + * + * This file is part of GNUTLS. + * + * GNUTLS 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 2 of the License, or + * (at your option) any later version. + * + * GNUTLS 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "gnutls_int.h" +#include "gnutls_errors.h" +#include "gnutls_mpi.h" +#include "gnutls_cert.h" +#include "gnutls_datum.h" +#include "gnutls_global.h" +#include "auth_cert.h" +#include "gnutls_openpgp.h" + +#ifdef HAVE_LIBOPENCDK + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OPENPGP_NAME_SIZE GNUTLS_X509_CN_SIZE + +typedef struct { + int type; + int armored; + size_t size; + byte *data; +} keybox_blob; + +typedef enum { + KBX_BLOB_FILE = 0x00, + KBX_BLOB_DATA = 0x01 +} keyring_blob_types; + +static void +release_mpi_array(GNUTLS_MPI *arr, size_t n) +{ + GNUTLS_MPI x; + + while ( arr && n-- ) + { + x = *arr; + _gnutls_mpi_release(&x); + *arr = NULL; arr++; + } +} + +static u32 +buffer_to_u32( const byte *buffer ) +{ + u32 u; + + if (!buffer) + return 0; + u = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]; + return u; +} + +static int +file_exist(const char *file) +{ + FILE *fp; + + if (!file) + return 0; + + fp = fopen(file, "r"); + if (fp) + { + fclose(fp); + return 1; + } + + return 0; +} + +static int +kbx_blob_new( keybox_blob **r_ctx ) +{ + keybox_blob *c; + + if ( !r_ctx ) + return GNUTLS_E_INVALID_PARAMETERS; + + c = cdk_alloc_clear( sizeof * c); + if ( !c ) + return GNUTLS_E_MEMORY_ERROR; + *r_ctx = c; + + return 0; +} /* kbx_blob_new */ + +static void +kbx_blob_release( keybox_blob *ctx ) +{ + if (!ctx) + return; + cdk_free(ctx->data); + cdk_free(ctx); +} /* kbx_blob_release */ + +static KEYDB_HD +kbx_to_keydb( keybox_blob *blob ) +{ + KEYDB_HD khd = NULL; + + if (!blob) + return NULL; + + khd = cdk_alloc_clear(sizeof *khd); + if ( !khd ) + return NULL; + khd->used = 1; + if ( blob->type == KBX_BLOB_FILE ) /* file */ + { + khd->name = cdk_strdup( blob->data ); + khd->type = blob->armored? KEYDB_TYPE_ARMORED: KEYDB_TYPE_KEYRING; + } + else if ( blob->type == KBX_BLOB_DATA ) /* data */ + { + cdk_iobuf_new( &khd->buf, blob->size ); + cdk_iobuf_write( khd->buf, blob->data, blob->size ); + khd->type = KEYDB_TYPE_DATA; + } + else /* error */ + { + cdk_free( khd ); + khd = NULL; + } + + return khd; +} /* kbx_to_keydb */ + +/* Extract a keybox blob from the given position. */ +static keybox_blob* +kbx_read_blob( const gnutls_datum* keyring, size_t pos ) +{ + keybox_blob *blob = NULL; + + if ( !keyring || !keyring->data ) + return NULL; + + if (pos > keyring->size) + return NULL; + + kbx_blob_new( &blob ); + blob->type = keyring->data[pos]; + if ( blob->type != KBX_BLOB_FILE && + blob->type != KBX_BLOB_DATA ) + { + kbx_blob_release( blob ); + return NULL; + } + blob->armored = keyring->data[pos+1]; + blob->size = buffer_to_u32( keyring->data+pos+2 ); + if (!blob->size) + { + kbx_blob_release( blob ); + return NULL; + } + blob->data = cdk_alloc_clear(blob->size + 1); + if ( !blob->data ) + return NULL; + memcpy(blob->data, keyring->data+(pos+6), blob->size); + blob->data[blob->size] = '\0'; + + return blob; +} /* kbx_read_blob */ + +/* Creates a keyring blob from raw data + * + * Format: + * 1 octet type + * 1 octet armored + * 4 octet size of blob + * n octets data + */ +static byte* +kbx_data_to_keyring( int type, int enc, const char *data, + size_t size, size_t *r_size ) +{ + byte *p = NULL; + + if (!data) + return NULL; + + p = gnutls_malloc( 1+4+size ); + if ( !p ) + return NULL; + p[0] = type; /* type: {keyring,name} */ + p[1] = enc; /* encoded: {plain, armored} */ + p[2] = (size >> 24) & 0xff; + p[3] = (size >> 16) & 0xff; + p[4] = (size >> 8) & 0xff; + p[5] = (size ) & 0xff; + memcpy( p+6, data, size ); + if ( r_size ) + *r_size = 6+size; + + return p; +} /* kbx_data_to_keyring */ + +static int +kbnode_to_datum( KBNODE kb_pk, gnutls_datum *raw ) +{ + KBNODE p = NULL; + byte *data = NULL; + size_t n = 0; + int rc = 0; + PACKET pkt = {0}; + IOBUF a; + + if (!kb_pk || !raw) + return GNUTLS_E_INVALID_PARAMETERS; + + /* fixme: conver the whole key */ + for (p=kb_pk; p && p->pkt->pkttype; p=p->next) + { + if (p->pkt->pkttype == PKT_PUBLIC_KEY) + { + a = cdk_iobuf_temp(); + pkt.pkttype = PKT_PUBLIC_KEY; + pkt.pkt.public_key = p->pkt->pkt.public_key; + rc = cdk_pkt_build( a, &pkt ); + if (rc) + return GNUTLS_E_UNKNOWN_ERROR; + data = cdk_iobuf_getdata(a, &n); + if (data && n) + { + rc = gnutls_set_datum(raw, data, n); + if (rc < 0) + return GNUTLS_E_MEMORY_ERROR; + } + cdk_free(data); + cdk_iobuf_close(a); + } + } + + return 0; +} + +static int +datum_to_kbnode( const gnutls_datum *raw, KBNODE *r_pkt ) +{ + IOBUF buf; + KBNODE pkt = NULL; + int dummy = 0; + int rc = 0; + + if (!raw || !r_pkt) + return GNUTLS_E_INVALID_PARAMETERS; + + cdk_iobuf_new( &buf, raw->size ); + cdk_iobuf_write( buf, raw->data, raw->size ); + rc = cdk_keydb_get_keyblock( buf, &pkt, &dummy ); + if ( rc && rc != CDKERR_EOF ) + { + rc = GNUTLS_E_NO_CERTIFICATE_FOUND; + goto leave; + } + else + rc = 0; + +leave: + cdk_iobuf_close( buf ); + *r_pkt = (!rc)? pkt : NULL; + + return rc; +} + +static int +iobuf_to_datum(IOBUF buf, gnutls_datum *raw) +{ + byte *data = NULL; + size_t nbytes = 0; + int rc = 0; + + if (!buf || !raw) + return GNUTLS_E_INVALID_PARAMETERS; + + data = cdk_iobuf_getdata(buf, &nbytes); + if (data && nbytes) + { + rc = gnutls_set_datum(raw, data, nbytes); + if (rc < 0) + return GNUTLS_E_MEMORY_ERROR; + cdk_free(data); + } + else + rc = GNUTLS_E_UNKNOWN_ERROR; + + return rc; +} + +static int +openpgp_pk_to_gnutls_cert(gnutls_cert *cert, PKT_public_key *pk) +{ + int algo, i; + int rc = 0; + size_t nbytes = 0; + + if (!cert || !pk) + return GNUTLS_E_INVALID_PARAMETERS; + + if ( is_ELG(pk->pubkey_algo) ) /* GnuTLS OpenPGP doesn't support ELG keys */ + return GNUTLS_E_UNWANTED_ALGORITHM; + + algo = is_DSA(pk->pubkey_algo)? GNUTLS_PK_DSA : GNUTLS_PK_RSA; + cert->subject_pk_algorithm = algo; + cert->version = pk->version; + cert->valid = 0; /* fixme: should set after the verification */ + cert->cert_type = GNUTLS_CRT_OPENPGP; + + if (is_DSA(pk->pubkey_algo) || pk->pubkey_algo == GCRY_PK_RSA_S) + cert->keyUsage = GNUTLS_X509KEY_DIGITAL_SIGNATURE; + else if (pk->pubkey_algo == GCRY_PK_RSA_E) + cert->keyUsage = GNUTLS_X509KEY_ENCIPHER_ONLY; + else if (pk->pubkey_algo == GCRY_PK_RSA) + cert->keyUsage = GNUTLS_X509KEY_DIGITAL_SIGNATURE + | GNUTLS_X509KEY_ENCIPHER_ONLY; + + cert->params_size = cdk_pk_get_npkey( pk->pubkey_algo ); + for (i=0; iparams_size; i++) + { + nbytes = pk->mpi[i].bytes+2; + rc = _gnutls_mpi_scan_pgp(&cert->params[i], + pk->mpi[i].data, &nbytes); + if (rc) + { + rc = GNUTLS_E_MPI_SCAN_FAILED; + goto leave; + } + } + cert->expiration_time = pk->expiredate; + cert->activation_time = pk->timestamp; + +leave: + if (rc) + release_mpi_array(cert->params, i-1); + + return rc; +} + +static int +openpgp_sig_to_gnutls_cert(gnutls_cert *cert, PKT_signature *sig) +{ + IOBUF buf = NULL; + int rc = 0; + size_t nbytes = 0; + size_t sigsize = 0; + byte *data = NULL; + PACKET pkt; + + if (!cert || !sig) + return GNUTLS_E_INVALID_PARAMETERS; + + sigsize = 20 + sig->hashed_size + sig->unhashed_size + 2*MAX_MPI_BYTES; + cdk_iobuf_new(&buf, sigsize); + memset( &pkt, 0, sizeof pkt ); + pkt.pkttype = PKT_SIGNATURE; + pkt.pkt.signature = sig; + rc = cdk_pkt_build( buf, &pkt ); + if (rc) + goto leave; + data = cdk_iobuf_getdata(buf, &nbytes); + if (data && nbytes) + { + rc = gnutls_datum_append( &cert->signature, data, nbytes); + if (rc < 0) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + cdk_free(data); + } + else + rc = GNUTLS_E_UNKNOWN_ERROR; + +leave: + cdk_iobuf_close(buf); + + return rc; +} + +/*- + * _gnutls_openpgp_key2gnutls_key - Converts an OpenPGP secret key to GnuTLS + * @pkey: the GnuTLS private key context to store the key. + * @raw_key: the raw data which contains the whole key packets. + * + * The RFC2440 (OpenPGP Message Format) data is converted into the + * GnuTLS specific data which is need to perform secret key operations. + -*/ +int +_gnutls_openpgp_key2gnutls_key( gnutls_private_key *pkey, + gnutls_datum raw_key ) +{ + KBNODE p = NULL, kb_sk; + PKT_secret_key *sk = NULL; + IOBUF buf; + int pke_algo, i, j, eof = 0; + size_t nbytes = 0; + int rc = 0; + + if (!pkey || raw_key.size <= 0) + return GNUTLS_E_INVALID_PARAMETERS; + + cdk_secmem_init( 16384 ); + cdk_iobuf_new(&buf, raw_key.size); + cdk_iobuf_write(buf, raw_key.data, raw_key.size); + + rc = cdk_keydb_get_keyblock( buf, &kb_sk, &eof ); + if ( !kb_sk || rc ) + { + rc = GNUTLS_E_UNKNOWN_ERROR; + goto leave; + } + p = cdk_kbnode_find( kb_sk, PKT_SECRET_KEY ); + if ( !p ) + { + rc = GNUTLS_E_NO_CERTIFICATE_FOUND; + goto leave; + } + sk = p->pkt->pkt.secret_key; + pke_algo = sk->pk->pubkey_algo; + pkey->params_size = cdk_pk_get_npkey( pke_algo ); + for (i=0; iparams_size; i++) + { + nbytes = sk->pk->mpi[i].bytes+2; + rc = _gnutls_mpi_scan_pgp(&pkey->params[i], + sk->pk->mpi[i].data, &nbytes); + if (rc) + { + rc = GNUTLS_E_MPI_SCAN_FAILED; + release_mpi_array(pkey->params, i-1); + goto leave; + } + } + pkey->params_size += cdk_pk_get_nskey( pke_algo ); + for (j=0; jmpi[j]->bytes+2; + rc = _gnutls_mpi_scan_pgp(&pkey->params[i], + sk->mpi[j]->data, &nbytes); + if (rc) + { + rc = GNUTLS_E_MPI_SCAN_FAILED; + release_mpi_array(pkey->params, i-1); + goto leave; + } + } + if ( is_ELG(pke_algo) ) + return GNUTLS_E_UNWANTED_ALGORITHM; + else if ( is_DSA(pke_algo) ) + pkey->pk_algorithm = GNUTLS_PK_DSA; + else if ( is_RSA(pke_algo) ) + pkey->pk_algorithm = GNUTLS_PK_RSA; + rc = gnutls_set_datum(&pkey->raw, raw_key.data, raw_key.size); + if (rc < 0) + { + release_mpi_array(pkey->params, i); + rc = GNUTLS_E_MEMORY_ERROR; + } + +leave: + cdk_iobuf_close(buf); + cdk_kbnode_release( kb_sk ); + + return rc; +} + +/*- + * _gnutls_openpgp_cert2gnutls_cert - Converts raw OpenPGP data to GnuTLS certs + * @cert: the certificate to store the data. + * @raw: the buffer which contains the whole OpenPGP key packets. + * + * The RFC2440 (OpenPGP Message Format) data is converted to a GnuTLS + * specific certificate. + -*/ +int +_gnutls_openpgp_cert2gnutls_cert(gnutls_cert *cert, gnutls_datum raw) +{ + KBNODE p, kb_pk = NULL; + PKT_public_key *pk = NULL; + int rc = 0; + + if (!cert) + return GNUTLS_E_INVALID_PARAMETERS; + + memset(cert, 0, sizeof *cert); + rc = datum_to_kbnode( &raw, &kb_pk ); + if ( rc ) + return rc; + p = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); + if ( !p ) + { + rc = GNUTLS_E_NO_CERTIFICATE_FOUND; + goto leave; + } + pk = p->pkt->pkt.public_key; + rc = gnutls_set_datum( &cert->raw, raw.data, raw.size ); + if (rc < 0) + { + rc = GNUTLS_E_MEMORY_ERROR; + goto leave; + } + rc = openpgp_pk_to_gnutls_cert( cert, pk ); + +leave: + cdk_kbnode_release( kb_pk ); + + return rc; +} + +/** + * gnutls_openpgp_get_key - Retrieve a key from the keyring. + * @key: the destination context to save the key. + * @keyring: the datum struct that contains all keyring information. + * @attr: The attribute (keyid, fingerprint, ...). + * @by: What attribute is used. + * + * This function can be used to retrieve keys by different pattern + * from a binary or a file keyring. + **/ +int +gnutls_openpgp_get_key(gnutls_datum *key, const gnutls_datum *keyring, + key_attr_t by, opaque *pattern) +{ + int rc = 0; + keybox_blob *blob = NULL; + KEYDB_HD khd = NULL; + KBNODE pk = NULL; + KEYDB_SEARCH ks; + + if (!key || !keyring || by == KEY_ATTR_NONE) + return GNUTLS_E_INVALID_PARAMETERS; + + blob = kbx_read_blob( keyring, 0 ); + if (!blob) + return GNUTLS_E_MEMORY_ERROR; + khd = kbx_to_keydb( blob ); + ks.type = by; + switch (by) + { + case KEY_ATTR_SHORT_KEYID: + ks.u.keyid[1] = buffer_to_u32(pattern); + break; + + case KEY_ATTR_KEYID: + ks.u.keyid[0] = buffer_to_u32(pattern); + ks.u.keyid[1] = buffer_to_u32(pattern+4); + break; + + case KEY_ATTR_FPR: + memcpy(ks.u.fpr, pattern, 20); + break; + + default: + goto leave; + } + + rc = cdk_keydb_search( khd, &ks, &pk ); + if (rc) + { + rc = GNUTLS_E_NO_CERTIFICATE_FOUND; + goto leave; + } + + if ( !cdk_kbnode_find( pk, PKT_PUBLIC_KEY ) ) + { + rc = GNUTLS_E_NO_CERTIFICATE_FOUND; + goto leave; + } + + rc = kbnode_to_datum( pk, key ); + +leave: + cdk_free( khd ); + cdk_kbnode_release( pk ); + kbx_blob_release( blob ); + + return rc; +} + +int +gnutls_certificate_set_openpgp_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, + gnutls_datum *cert, + gnutls_datum *key) +{ + gnutls_datum raw; + KBNODE kb_pk = NULL, pkt; + int rc = 0; + int i; + + if (!res || !key || !cert) + return GNUTLS_E_INVALID_PARAMETERS; + + rc = datum_to_kbnode( cert, &kb_pk ); + if (rc) + goto leave; + + /* fixme: too much duplicated code from (set_openpgp_key_file) */ + res->cert_list = gnutls_realloc(res->cert_list, + (1+res->ncerts)*sizeof(gnutls_cert*)); + if (res->cert_list == NULL) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + res->cert_list_length = gnutls_realloc(res->cert_list_length, + (1+res->ncerts)*sizeof(int)); + if (res->cert_list_length == NULL) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + res->cert_list[res->ncerts] = gnutls_calloc(1, sizeof(gnutls_cert)); + if (res->cert_list[res->ncerts] == NULL) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + for (i=1, pkt=kb_pk; pkt && pkt->pkt->pkttype; pkt=pkt->next) + { + if (i > MAX_PARAMS_SIZE) + break; + if (pkt->pkt->pkttype == PKT_PUBLIC_KEY) + { + int n = res->ncerts; + PKT_public_key *pk = pkt->pkt->pkt.public_key; + res->cert_list_length[n] = 1; + gnutls_set_datum(&res->cert_list[n][0].raw, cert->data, cert->size); + openpgp_pk_to_gnutls_cert( &res->cert_list[n][0], pk ); + i++; + } + else if (pkt->pkt->pkttype == PKT_SIGNATURE) + { + int n = res->ncerts; + PKT_signature *sig = pkt->pkt->pkt.signature; + openpgp_sig_to_gnutls_cert( &res->cert_list[n][0], sig ); + } + } + + res->ncerts++; + res->pkey = gnutls_realloc(res->pkey, + (res->ncerts)*sizeof(gnutls_private_key)); + if (res->pkey == NULL) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + /* ncerts has been incremented before */ + gnutls_set_datum(&raw, key->data, key->size); + rc =_gnutls_openpgp_key2gnutls_key( &res->pkey[res->ncerts-1], raw); + gnutls_free_datum(&raw); + +leave: + cdk_kbnode_release( kb_pk ); + + return rc; +} + +/** + * gnutls_certificate_set_openpgp_key_file - Used to set OpenPGP keys + * @res: the destination context to save the data. + * @CERTFILE: the file that contains the public key. + * @KEYFILE: the file that contains the secret key. + * + * This funtion is used to load OpenPGP keys into the GnuTLS structure. + * It doesn't matter whether the keys are armored or but, but the files + * should only contain one key which should not be encrypted. + **/ +int +gnutls_certificate_set_openpgp_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res, + char* CERTFILE, + char* KEYFILE) +{ + IOBUF inp = NULL; + KBNODE kb_pk = NULL, pkt; + armor_filter_s afx; + gnutls_datum raw; + int eof = 0, i = 0; + int rc = 0; + + if (!res || !KEYFILE || !CERTFILE) + return GNUTLS_E_INVALID_PARAMETERS; + + if ( !file_exist(CERTFILE) || !file_exist(KEYFILE) ) + return GNUTLS_E_FILE_ERROR; + + rc = cdk_iobuf_open(&inp, CERTFILE, IOBUF_MODE_RD); + if ( rc ) + return GNUTLS_E_FILE_ERROR; + if ( cdk_armor_filter_use( inp ) ) + { + memset( &afx, 0, sizeof afx ); + rc = cdk_iobuf_push_filter( inp, &afx, cdk_armor_filter ); + if ( rc ) + { + cdk_iobuf_close( inp ); + rc = GNUTLS_E_ASCII_ARMOR_ERROR; + goto leave; + } + /*cdk_iobuf_close( inp );*/ + } + + res->cert_list = gnutls_realloc(res->cert_list, + (1+res->ncerts)*sizeof(gnutls_cert*)); + if (res->cert_list == NULL) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + res->cert_list_length = gnutls_realloc(res->cert_list_length, + (1+res->ncerts)*sizeof(int)); + if (res->cert_list_length == NULL) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + res->cert_list[res->ncerts] = gnutls_calloc(1, sizeof(gnutls_cert)); + if (res->cert_list[res->ncerts] == NULL) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + do { + rc = cdk_keydb_get_keyblock( inp, &kb_pk, &eof ); + if ( !kb_pk || rc ) + break; + for (i=1, pkt=kb_pk; pkt && pkt->pkt->pkttype; pkt=pkt->next) + { + if (i > MAX_PARAMS_SIZE) + break; + if (pkt->pkt->pkttype == PKT_PUBLIC_KEY) + { + int n = res->ncerts; + PKT_public_key *pk = pkt->pkt->pkt.public_key; + res->cert_list_length[n] = 1; + iobuf_to_datum(inp, &res->cert_list[n][0].raw); + openpgp_pk_to_gnutls_cert( &res->cert_list[n][0], pk ); + i++; + } + else if (pkt->pkt->pkttype == PKT_SIGNATURE) + { + int n = res->ncerts; + PKT_signature *sig = pkt->pkt->pkt.signature; + openpgp_sig_to_gnutls_cert( &res->cert_list[n][0], sig ); + } + } + } while (!eof && !rc); + + cdk_iobuf_close(inp); + if ( rc ) + { + cdk_kbnode_release( kb_pk ); + rc = GNUTLS_E_UNKNOWN_ERROR; + goto leave; + } + cdk_kbnode_release( kb_pk ); + + rc = cdk_iobuf_open( &inp, KEYFILE, IOBUF_MODE_RD ); + if ( rc ) + return GNUTLS_E_FILE_ERROR; + if ( cdk_armor_filter_use( inp ) ) + { + memset( &afx, 0, sizeof afx ); + rc = cdk_iobuf_push_filter( inp, &afx, cdk_armor_filter ); + if ( rc ) + { + cdk_iobuf_close( inp ); + rc = GNUTLS_E_ASCII_ARMOR_ERROR; + goto leave; + } + /*cdk_iobuf_close( inp );*/ + } + + iobuf_to_datum( inp, &raw ); + cdk_iobuf_close( inp ); + + res->pkey = gnutls_realloc(res->pkey, + (res->ncerts+1)*sizeof(gnutls_private_key)); + if (res->pkey == NULL) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + res->ncerts++; + + /* ncerts has been incremented before */ + rc =_gnutls_openpgp_key2gnutls_key( &res->pkey[res->ncerts-1], raw); + +leave: + + return rc; +} + +int +gnutls_openpgp_count_key_names( const gnutls_datum *cert ) +{ + KBNODE kb_pk = NULL, pkt; + int nuids = 0; + + if ( !cert ) + return 0; + + if ( datum_to_kbnode( cert, &kb_pk ) ) + return 0; + for ( pkt=kb_pk; pkt; pkt=pkt->next ) + { + if ( pkt->pkt->pkttype == PKT_USER_ID ) + nuids++; + } + return nuids; +} /* gnutls_openpgp_count_key_names */ + +/** + * gnutls_openpgp_extract_key_name - Extracts the userID + * @cert: the raw data that contains the OpenPGP public key. + * @dn: the structure to store the userID specific data in. + * + * Extracts the userID from the raw OpenPGP key. + **/ +int +gnutls_openpgp_extract_key_name( const gnutls_datum *cert, + int idx, + gnutls_openpgp_name *dn ) +{ + KBNODE kb_pk = NULL, pkt; + PKT_user_id *uid = NULL; + char *email; + int rc = 0; + int pos1 = 0, pos2 = 0; + size_t size = 0; + int pos = 0; + + if (!cert || !dn) + return GNUTLS_E_INVALID_PARAMETERS; + + if ( idx < 0 || idx > gnutls_openpgp_count_key_names( cert ) ) + return GNUTLS_E_UNKNOWN_ERROR; + + memset(dn, 0, sizeof *dn); + rc = datum_to_kbnode( cert, &kb_pk ); + if ( rc ) + return rc; + if ( !idx ) + pkt = cdk_kbnode_find( kb_pk, PKT_USER_ID ); + else + { + for ( pos=0, pkt=kb_pk; pkt; pkt=pkt->next ) + { + if ( pkt->pkt->pkttype == PKT_USER_ID && ++pos == idx ) + break; + } + } + if ( pkt ) + uid = pkt->pkt->pkt.user_id; + if ( !uid ) + { + rc = GNUTLS_E_UNKNOWN_ERROR; + goto leave; + } + size = uid->len < OPENPGP_NAME_SIZE? uid->len : OPENPGP_NAME_SIZE-1; + memcpy(dn->name, uid->name, size); + dn->name[size] = '\0'; /* make sure it's a string */ + + /* Extract the email address from the userID string and save + it to the email field. */ + email = strchr(uid->name, '<'); + if ( email ) + pos1 = email-uid->name+1; + email = strchr(uid->name, '>'); + if ( email ) + pos2 = email-uid->name+1; + if (pos1 && pos2) + { + pos2 -= pos1; + size = pos2 < OPENPGP_NAME_SIZE? pos2 : OPENPGP_NAME_SIZE-1; + memcpy(dn->email, uid->name+pos1, size); + dn->email[size-1] = '\0'; /* make sure it's a string */ + } + if ( uid->is_revoked ) + { + rc = GNUTLS_E_OPENPGP_UID_REVOKED; + goto leave; + } + +leave: + cdk_kbnode_release( kb_pk ); + + return rc; +} + +/** + * gnutls_openpgp_extract_key_pk_algorithm - This function returns the key's PublicKey algorithm + * @cert: is an OpenPGP key + * @bits: if bits is non null it will hold the size of the parameters' in bits + * + * This function will return the public key algorithm of an OpenPGP + * certificate. + * + * If bits is non null, it should have enough size to hold the parameters + * size in bits. For RSA the bits returned is the modulus. + * For DSA the bits returned are of the public exponent. + * + * Returns a member of the GNUTLS_PKAlgorithm enumeration on success, + * or a negative value on error. + * + **/ +int +gnutls_openpgp_extract_key_pk_algorithm(const gnutls_datum *cert, int *r_bits) +{ + KBNODE kb_pk = NULL, pkt; + int algo = 0; + + if ( !cert ) + return GNUTLS_E_INVALID_PARAMETERS; + + if ( datum_to_kbnode( cert, &kb_pk ) ) + return 0; + pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); + if ( pkt && r_bits) + *r_bits = cdk_pk_get_nbits( pkt->pkt->pkt.public_key ); + algo = pkt->pkt->pkt.public_key->pubkey_algo; + if ( is_RSA( algo ) ) + algo = GNUTLS_PK_RSA; + else if ( is_DSA( algo ) ) + algo = GNUTLS_PK_DSA; + else + algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM; + cdk_kbnode_release( kb_pk ); + + return algo; +} + + +/** + * gnutls_openpgp_extract_key_version - Extracts the version of the key. + * @cert: the raw data that contains the OpenPGP public key. + * + * Extract the version of the OpenPGP key. + **/ +int +gnutls_openpgp_extract_key_version( const gnutls_datum *cert ) +{ + KBNODE kb_pk = NULL, pkt; + int version = 0; + + if (!cert) + return GNUTLS_E_INVALID_PARAMETERS; + + if ( datum_to_kbnode( cert, &kb_pk ) ) + return 0; + pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); + if ( pkt ) + version = pkt->pkt->pkt.public_key->version; + cdk_kbnode_release( kb_pk ); + + return version; +} + +/** + * gnutls_openpgp_extract_key_creation_time - Extract the timestamp + * @cert: the raw data that contains the OpenPGP public key. + * + * Returns the timestamp when the OpenPGP key was created. + **/ +time_t +gnutls_openpgp_extract_key_creation_time( const gnutls_datum *cert ) +{ + KBNODE kb_pk = NULL, pkt; + time_t timestamp = 0; + + if (!cert) + return GNUTLS_E_INVALID_PARAMETERS; + + if ( datum_to_kbnode( cert, &kb_pk ) ) + return 0; + pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); + if ( pkt ) + timestamp = pkt->pkt->pkt.public_key->timestamp; + cdk_kbnode_release( kb_pk ); + + return timestamp; +} + +/** + * gnutls_openpgp_extract_key_expiration_time - Extract the expire date + * @cert: the raw data that contains the OpenPGP public key. + * + * Returns the time when the OpenPGP key expires. A value of '0' means + * that the key doesn't expire at all. + **/ +time_t +gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert ) +{ + KBNODE kb_pk = NULL, pkt; + time_t expiredate = 0; + + if (!cert) + return GNUTLS_E_INVALID_PARAMETERS; + + if ( datum_to_kbnode( cert, &kb_pk ) ) + return 0; + pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); + if ( pkt ) + expiredate = pkt->pkt->pkt.public_key->expiredate; + cdk_kbnode_release( kb_pk ); + + return expiredate; +} + +int +_gnutls_openpgp_get_key_trust(const char *trustdb, + const gnutls_datum *key, + int *r_success) +{ + int flags = 0; + int ot = 0, trustval = 0; + int rc = 0; + KBNODE kb_pk = NULL, pkt; + PKT_public_key *pk = NULL; + IOBUF buf; + + if (!trustdb || !key || !r_success) + return GNUTLS_E_NO_CERTIFICATE_FOUND; + + *r_success = 0; + rc = datum_to_kbnode( key, &kb_pk ); + if ( rc ) + return GNUTLS_E_NO_CERTIFICATE_FOUND; + + pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); + if ( pkt ) + pk = pkt->pkt->pkt.public_key; + if ( !pk ) + return GNUTLS_E_NO_CERTIFICATE_FOUND; + + rc = cdk_iobuf_open( &buf, trustdb, IOBUF_MODE_RD ); + if ( rc ) + { + trustval = GNUTLS_E_NO_CERTIFICATE_FOUND; + goto leave; + } + rc = cdk_trustdb_get_ownertrust( buf, pk, &ot, &flags ); + cdk_iobuf_close( buf ); + if ( rc ) /* no ownertrust record was found */ + { + trustval = 0; + *r_success = 1; + goto leave; + } + + if (flags & TRUST_FLAG_DISABLED) + { + trustval |= GNUTLS_CERT_NOT_TRUSTED; + trustval |= GNUTLS_CERT_INVALID; + goto leave; + } + if (flags & TRUST_FLAG_REVOKED) + { + trustval |= GNUTLS_CERT_NOT_TRUSTED; + trustval |= GNUTLS_CERT_REVOKED; + } + switch (ot) + { + case TRUST_NEVER: + trustval |= GNUTLS_CERT_NOT_TRUSTED; + break; + + case TRUST_UNKNOWN: + case TRUST_UNDEFINED: + case TRUST_MARGINAL: + + case TRUST_FULLY: + case TRUST_ULTIMATE: + trustval |= 1; /* means okay */ + *r_success = 1; + break; + } + +leave: + cdk_kbnode_release( kb_pk ); + return trustval; +} + +/** + * gnutls_openpgp_verify_key - Verify all signatures on the key + * @cert_list: the structure that holds the certificates. + * @cert_list_lenght: the items in the cert_list. + * + * Verify all signatures in the certificate list. When the key + * is not available, the signature is skipped. + * The return value is one of the CertificateStatus entries. + **/ +int +gnutls_openpgp_verify_key( const char *trustdb, + const gnutls_datum* keyring, + const gnutls_datum* cert_list, + int cert_list_length ) +{ + KBNODE kb_pk = NULL; + KEYDB_HD khd = NULL; + keybox_blob *blob = NULL; + int rc = 0; + int status = 0; + + if (!cert_list || !cert_list_length || !keyring) + return GNUTLS_E_NO_CERTIFICATE_FOUND; + + if (cert_list_length != 1 || !keyring->size) + return GNUTLS_E_NO_CERTIFICATE_FOUND; + + blob = kbx_read_blob(keyring, 0); + if (!blob) + return GNUTLS_CERT_INVALID|GNUTLS_CERT_NOT_TRUSTED; + khd = kbx_to_keydb(blob); + if (!khd) + { + rc = GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED; + goto leave; + } + + if ( trustdb ) + { + int success = 0; + rc = _gnutls_openpgp_get_key_trust(trustdb, cert_list, &success); + if (!success) + goto leave; + } + + rc = datum_to_kbnode( cert_list, &kb_pk ); + if (rc) + { + goto leave; + return GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED; + } + + rc = cdk_key_check_sigs( kb_pk, khd, &status ); + if (rc == CDKERR_NOKEY) + rc = 0; /* fixme */ + + switch (status) + { + case CDK_KEY_INVALID: + rc = GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED; + break; + + case CDK_KEY_REVOKED: + rc = GNUTLS_CERT_REVOKED | GNUTLS_CERT_NOT_TRUSTED; + break; + + } + +leave: + kbx_blob_release( blob ); + cdk_free( khd ); + cdk_kbnode_release( kb_pk ); + + return rc; +} + +/** + * gnutls_openpgp_fingerprint - Gets the fingerprint + * @cert: the raw data that contains the OpenPGP public key. + * @fpr: the buffer to save the fingerprint. + * @fprlen: the integer to save the length of the fingerprint. + * + * Returns the fingerprint of the OpenPGP key. Depence on the algorithm, + * the fingerprint can be 16 or 20 bytes. + **/ +int +gnutls_openpgp_fingerprint(const gnutls_datum *cert, byte *fpr, size_t *fprlen) +{ + KBNODE kb_pk = NULL, pkt; + PKT_public_key *pk = NULL; + int rc = 0; + + if (!cert || !fpr || !fprlen) + return GNUTLS_E_UNKNOWN_ERROR; + + *fprlen = 0; + rc = datum_to_kbnode( cert, &kb_pk ); + if (rc) + return rc; + pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); + if ( pkt ) + pk = pkt->pkt->pkt.public_key; + if ( !pk ) + return GNUTLS_E_UNKNOWN_ERROR; + + *fprlen = 20; + if ( is_RSA(pk->pubkey_algo) && pk->version < 4 ) + *fprlen = 16; + cdk_pk_get_fingerprint( pk, fpr ); + + return 0; +} + +/** + * gnutls_openpgp_keyid - Gets the keyID + * @cert: the raw data that contains the OpenPGP public key. + * @keyid: the buffer to save the keyid. + * + * Returns the 64-bit keyID of the OpenPGP key. + **/ +int +gnutls_openpgp_keyid( const gnutls_datum *cert, uint32 *keyid ) +{ + KBNODE kb_pk = NULL, pkt; + PKT_public_key *pk = NULL; + int rc = 0; + + if (!cert || !keyid) + return GNUTLS_E_UNKNOWN_ERROR; + + rc = datum_to_kbnode( cert, &kb_pk ); + if (rc) + return rc; + + pkt = cdk_kbnode_find( kb_pk, PKT_PUBLIC_KEY ); + if ( pkt ) + pk = pkt->pkt->pkt.public_key; + if ( !pk ) + return GNUTLS_E_UNKNOWN_ERROR; + cdk_pk_get_keyid( pk, (u32 *)keyid ); + + return 0; +} + +/** + * gnutls_openpgp_add_keyring_file - Adds a keyring file for OpenPGP + * @keyring: data buffer to store the file. + * @name: filename of the keyring. + * + * The function is used to set keyrings that will be used internally + * by various OpenCDK functions. For example to find a key when it + * is needed for an operations. + **/ +int +gnutls_openpgp_add_keyring_file(gnutls_datum *keyring, const char *name) +{ + byte *blob; + size_t nbytes; + IOBUF inp = NULL; + int enc = 0; + int rc = 0; + + if (!keyring || !name) + return GNUTLS_E_INVALID_PARAMETERS; + + rc = cdk_iobuf_open( &inp, name, IOBUF_MODE_RD ); + if ( rc ) + return GNUTLS_E_FILE_ERROR; + enc = cdk_armor_filter_use( inp ); + cdk_iobuf_close( inp ); + + blob = kbx_data_to_keyring( KBX_BLOB_FILE, enc, name, strlen(name), &nbytes); + if (blob && nbytes) + { + if ( gnutls_datum_append( keyring, blob, nbytes ) < 0 ) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + gnutls_free(blob); + } + + return 0; +} + +/** + * gnutls_openpgp_add_keyring_mem - Adds keyring data for OpenPGP + * @keyring: data buffer to store the file. + * @data: the binary data of the keyring. + * @len: the size of the binary buffer. + * + * Same as gnutls_openpgp_add_keyring_mem but now we store the + * data instead of the filename. + **/ +int +gnutls_openpgp_add_keyring_mem(gnutls_datum *keyring, + const char *data, size_t len) +{ + byte *blob; + size_t nbytes = 0; + + if (!keyring || !data || !len) + return GNUTLS_E_INVALID_PARAMETERS; + + blob = kbx_data_to_keyring( KBX_BLOB_DATA, 0, data, len, &nbytes ); + if ( blob && nbytes ) + { + if ( gnutls_datum_append( keyring, blob, nbytes ) < 0 ) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + gnutls_free(blob); + } + + return 0; +} + +int +gnutls_certificate_set_openpgp_keyring_file(GNUTLS_CERTIFICATE_CREDENTIALS c, + const char *file) +{ + if (!c || !file) + return GNUTLS_E_INVALID_PARAMETERS; + + if ( !file_exist(file) ) + return GNUTLS_E_FILE_ERROR; + + return gnutls_openpgp_add_keyring_file(&c->keyring, file); +} + +int +gnutls_certificate_set_openpgp_keyring_mem(GNUTLS_CERTIFICATE_CREDENTIALS c, + const char *file) +{ + IOBUF inp = NULL; + byte *data = NULL; + size_t nbytes = 0; + armor_filter_s afx; + int rc = 0; + + if (!c || !file) + return GNUTLS_E_INVALID_PARAMETERS; + + if ( !file_exist(file) ) + return GNUTLS_E_FILE_ERROR; + + rc = cdk_iobuf_open(&inp, file, IOBUF_MODE_RD); + if ( rc ) + return GNUTLS_E_FILE_ERROR; + if ( cdk_armor_filter_use( inp ) ) + { + memset( &afx, 0, sizeof afx ); + rc = cdk_iobuf_push_filter( inp, &afx, cdk_armor_filter ); + if ( rc ) + { + cdk_iobuf_close( inp ); + return GNUTLS_E_ASCII_ARMOR_ERROR; + } + } + + data = cdk_iobuf_getdata( inp, &nbytes ); + if (data && nbytes) + { + rc = gnutls_openpgp_add_keyring_mem( &c->keyring, data, nbytes ); + cdk_free(data); + } + else + rc = GNUTLS_E_UNKNOWN_ERROR; + cdk_iobuf_close(inp); + + return rc; +} + +/** + * gnutls_openpgp_recv_key - Receives a key from a HKP keyserver. + * @host - the hostname of the keyserver. + * @port - the service port (if not set use 11371). + * @keyid - The 32-bit keyID (rightmost bits keyid[1]) + * @key - Context to store the raw (dearmored) key. + * + * Try to connect to a public keyserver to get the specified key. + **/ +int +gnutls_openpgp_recv_key(const char *host, short port, uint32 keyid, + gnutls_datum *key) +{ + int rc = 0, state = 0; + struct hostent *hp; + struct sockaddr_in sock; + armor_filter_s afx; + char *request = NULL; + char buffer[4096]; + IOBUF buf = NULL; + int fd = -1; + byte *data; + ssize_t n = 0, nbytes = 0; + + if (!host || !key) + return GNUTLS_E_INVALID_PARAMETERS; + + if (!port) + port = 11371; /* standard service port */ + + hp = gethostbyname(host); + if (hp == NULL) + return -1; + + memset(&sock, 0, sizeof sock); + memcpy(&sock.sin_addr, hp->h_addr, hp->h_length); + sock.sin_family = hp->h_addrtype; + sock.sin_port = htons(port); + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) + return -1; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)1, 1); + if ( connect(fd, (struct sockaddr*)&sock, sizeof(sock)) == -1 ) + { + close(fd); + return -1; + } + + request = cdk_alloc_clear(strlen(host)+100); + if ( request == NULL ) + { + close( fd ); + return -1; + } + sprintf(request, "GET /pks/lookup?op=get&search=0x%08X HTTP/1.0\r\n" + "Host: %s:%d\r\n", (u32)keyid, host, port); + if ( write(fd, request, strlen(request)) == -1 ) + { + cdk_free(request); + close(fd); + return -1; + } + cdk_free(request); + + buf = cdk_iobuf_temp(); + while ( (n = read(fd, buffer, sizeof(buffer)-1)) > 0 ) + { + buffer[n] = '\0'; + nbytes += n; + if ( nbytes > cdk_iobuf_getsize( buf ) ) + cdk_iobuf_expand(buf, n); + cdk_iobuf_write(buf, buffer, n); + if ( strstr(buffer, "
") || strstr(buffer, "
") ) + state++; + } + + if (state != 2) + { + rc = GNUTLS_E_UNKNOWN_ERROR; + goto leave; + } + memset(&afx, 0, sizeof afx); + rc = cdk_iobuf_push_filter(buf, &afx, cdk_armor_filter); + if (rc) + { + rc = GNUTLS_E_ASCII_ARMOR_ERROR; + goto leave; + } + data = cdk_iobuf_getdata(buf, &n); + if (data && n) + { + gnutls_set_datum(key, data, n); + cdk_free(data); + } + +leave: + cdk_iobuf_close(buf); + close(fd); + + return 0; +} + +/*- + * _gnutls_openpgp_request_key - Receives a key from a database, key server etc + * @ret - a pointer to gnutls_datum structure. + * @cred - a GNUTLS_CERTIFICATE_CREDENTIALS structure. + * @key_fingerprint - The keyFingerprint + * @key_fingerprint_size - the size of the fingerprint + * + * Retrieves a key from a local database, keyring, or a key server. The + * return value is locally allocated. + * + -*/ +int +_gnutls_openpgp_request_key( gnutls_datum* ret, + const GNUTLS_CERTIFICATE_CREDENTIALS cred, + opaque* key_fpr, + int key_fpr_size) +{ + int rc = 0; + uint32 keyid; + + if (!ret || !cred || !key_fpr) + return GNUTLS_E_INVALID_PARAMETERS; + + if (key_fpr_size != 16 && key_fpr_size != 20) + return GNUTLS_E_HASH_FAILED; /* only MD5 and SHA1 are supported */ + + rc = gnutls_openpgp_get_key(ret, &cred->keyring, KEY_ATTR_FPR, key_fpr); + if (rc >= 0) + goto leave; + + keyid = buffer_to_u32(key_fpr+16); + rc = gnutls_openpgp_recv_key(cred->pgp_key_server, + cred->pgp_key_server_port, + keyid, ret); + +leave: + return rc; +} + +/** + * gnutls_certificate_set_openpgp_keyserver - Used to set an OpenPGP key server + * @res: the destination context to save the data. + * @server: is the key server address + * @port: is the key server port to connect to + * + * This funtion will set a key server for use with openpgp keys. This + * key server will only be used if the peer sends a key fingerprint instead + * of a key in the handshake. Using a key server may delay the handshake + * process. + * + **/ +void +gnutls_certificate_set_openpgp_keyserver(GNUTLS_CERTIFICATE_CREDENTIALS res, + char* keyserver, + int port) +{ + if (!res || !keyserver) + return; + + if (!port) + port = 11371; + + res->pgp_key_server = gnutls_strdup( keyserver ); + res->pgp_key_server_port = port; +} + +void +gnutls_certificate_set_openpgp_trustdb(GNUTLS_CERTIFICATE_CREDENTIALS res, + char* trustdb) +{ + if (!res || !trustdb) + return; + + res->pgp_trustdb = gnutls_strdup(trustdb); +} + +#else /*!HAVE_LIBOPENCDK*/ + +int +_gnutls_openpgp_key2gnutls_key(gnutls_private_key *pkey, + gnutls_datum raw_key) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int +_gnutls_openpgp_cert2gnutls_cert(gnutls_cert *cert, gnutls_datum raw) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int +gnutls_certificate_set_openpgp_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, + gnutls_datum *cert, + gnutls_datum *key) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int +gnutls_certificate_set_openpgp_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res, + char* CERTFILE, + char* KEYFILE) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int +gnutls_openpgp_extract_key_name( const gnutls_datum *cert, int idx, + gnutls_openpgp_name *dn ) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int +gnutls_openpgp_extract_key_pk_algorithm(const gnutls_datum *cert, int *r_bits) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int +gnutls_openpgp_extract_key_version( const gnutls_datum *cert ) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +time_t +gnutls_openpgp_extract_key_creation_time( const gnutls_datum *cert ) +{ + return (time_t)-1; +} + +time_t +gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert ) +{ + return (time_t)-1; +} + +int +gnutls_openpgp_verify_key(const char* ign, const gnutls_datum* keyring, + const gnutls_datum* cert_list, + int cert_list_length) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int +gnutls_openpgp_fingerprint(const gnutls_datum *cert, byte *fpr, size_t *fprlen) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int +gnutls_openpgp_add_keyring_file(gnutls_datum *keyring, const char *name) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int +gnutls_openpgp_add_keyring_mem(gnutls_datum *keyring, + const char *data, size_t len) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int +gnutls_certificate_set_openpgp_keyring_file(GNUTLS_CERTIFICATE_CREDENTIALS c, + const char *file) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int +gnutls_certificate_set_openpgp_keyring_mem(GNUTLS_CERTIFICATE_CREDENTIALS c, + const char *file) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int +_gnutls_openpgp_request_key( gnutls_datum* ret, + const GNUTLS_CERTIFICATE_CREDENTIALS cred, + opaque* key_fpr, + int key_fpr_size) +{ + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +void +gnutls_certificate_set_openpgp_keyserver(GNUTLS_CERTIFICATE_CREDENTIALS res, + char* keyserver, + int port) +{ + return; +} + +void +gnutls_certificate_set_openpgp_trustdb(GNUTLS_CERTIFICATE_CREDENTIALS res, + char* trustdb) +{ + return; +} + +#endif /* HAVE_LIBOPENCDK */ + + + + + + diff --git a/libextra/gnutls_openpgp.h b/libextra/gnutls_openpgp.h new file mode 100644 index 0000000000..a0ec4dd2e1 --- /dev/null +++ b/libextra/gnutls_openpgp.h @@ -0,0 +1,73 @@ +#ifndef GNUTLS_OPENPGP_H +#define GNUTLS_OPENPGP_H + +#include + +/* OpenCDK compatible */ +typedef enum { + KEY_ATTR_NONE = 0, + KEY_ATTR_SHORT_KEYID = 3, + KEY_ATTR_KEYID = 4, + KEY_ATTR_FPR = 5 +} key_attr_t; + +int gnutls_certificate_set_openpgp_key_file( + GNUTLS_CERTIFICATE_CREDENTIALS res, + char* CERTFILE, + char* KEYFILE); + +int gnutls_openpgp_count_key_names( const gnutls_datum *cert ); + +int gnutls_openpgp_extract_key_name( const gnutls_datum *cert, + int idx, + gnutls_openpgp_name *dn ); + +int gnutls_openpgp_extract_key_pk_algorithm(const gnutls_datum *cert, + int *r_bits); + +int gnutls_openpgp_extract_key_version( const gnutls_datum *cert ); + +time_t gnutls_openpgp_extract_key_creation_time( const gnutls_datum *cert ); + +time_t gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert ); + +int gnutls_openpgp_verify_key( const char *trustdb, + const gnutls_datum *keyring, + const gnutls_datum* cert_list, + int cert_list_length ); + +int gnutls_openpgp_fingerprint( const gnutls_datum *cert, opaque *fpr, + size_t *fprlen ); + +int gnutls_openpgp_keyid( const gnutls_datum *cert, uint32 *keyid ); + +int gnutls_openpgp_add_keyring_mem(gnutls_datum *keyring, + const char *data, size_t len); + +int gnutls_openpgp_add_keyring_file(gnutls_datum *keyring, const char *name); + +int gnutls_certificate_set_openpgp_keyring_file( + GNUTLS_CERTIFICATE_CREDENTIALS c, + const char *file); +int gnutls_certificate_set_openpgp_keyring_mem( + GNUTLS_CERTIFICATE_CREDENTIALS c, + const char *file); + +int gnutls_openpgp_get_key(gnutls_datum *key, const gnutls_datum *keyring, + key_attr_t by, opaque *pattern); + +int gnutls_openpgp_get_key_trust(const char *trustdb, gnutls_datum *key); + + +int gnutls_openpgp_recv_key(const char *host, short port, uint32 keyid, + gnutls_datum *key); + +/* internal */ +int _gnutls_openpgp_cert2gnutls_cert(gnutls_cert *cert, gnutls_datum raw); + +int +_gnutls_openpgp_request_key( gnutls_datum* ret, + const GNUTLS_CERTIFICATE_CREDENTIALS cred, opaque* key_fpr, + int key_fpr_size); + +#endif /*GNUTLS_OPENPGP_H*/ diff --git a/libextra/gnutls_srp.c b/libextra/gnutls_srp.c new file mode 100644 index 0000000000..e4eb030ba3 --- /dev/null +++ b/libextra/gnutls_srp.c @@ -0,0 +1,568 @@ +/* + * Copyright (C) 2001 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * GNUTLS 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 2 of the License, or + * (at your option) any later version. + * + * GNUTLS 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include + +#ifdef ENABLE_SRP + +#include +#include +#include +#include +#include "debug.h" + + +/* Here functions for SRP (like g^x mod n) are defined + */ + + +int _gnutls_srp_gx(opaque * text, int textsize, opaque ** result, GNUTLS_MPI g, + GNUTLS_MPI prime) +{ + + GNUTLS_MPI x, e; + int result_size; + + if (_gnutls_mpi_scan(&x, text, &textsize)) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + e = _gnutls_mpi_alloc_like(prime); + if (e==NULL) { + gnutls_assert(); + _gnutls_mpi_release(&x); + return GNUTLS_E_MEMORY_ERROR; + } + + /* e = g^x mod prime (n) */ + _gnutls_mpi_powm(e, g, x, prime); + _gnutls_mpi_release(&x); + + _gnutls_mpi_print( NULL, &result_size, e); + if (result != NULL) { + *result = gnutls_malloc(result_size); + if ((*result)==NULL) return GNUTLS_E_MEMORY_ERROR; + + _gnutls_mpi_print( *result, &result_size, e); + } + + _gnutls_mpi_release(&e); + + return result_size; + +} + + +/**************** + * Choose a random value b and calculate B = (v + g^b) % N. + * Return: B and if ret_b is not NULL b. + */ +GNUTLS_MPI _gnutls_calc_srp_B(GNUTLS_MPI * ret_b, GNUTLS_MPI g, GNUTLS_MPI n, GNUTLS_MPI v) +{ + GNUTLS_MPI tmpB; + GNUTLS_MPI b, B; + int bits; + + /* calculate: B = (v + g^b) % N */ + bits = _gnutls_mpi_get_nbits(n); + b = _gnutls_mpi_new(bits); /* FIXME: allocate in secure memory */ + if (b==NULL) { + gnutls_assert(); + return NULL; + } + + _gnutls_mpi_randomize(b, bits, GCRY_STRONG_RANDOM); + + tmpB = _gnutls_mpi_new(bits); /* FIXME: allocate in secure memory */ + if (tmpB==NULL) { + gnutls_assert(); + _gnutls_mpi_release( &b); + return NULL; + } + + B = _gnutls_mpi_new(bits); /* FIXME: allocate in secure memory */ + if (tmpB==NULL) { + gnutls_assert(); + _gnutls_mpi_release( &b); + _gnutls_mpi_release( &tmpB); + return NULL; + } + + _gnutls_mpi_powm(tmpB, g, b, n); + _gnutls_mpi_addm(B, v, tmpB, n); + + _gnutls_mpi_release(&tmpB); + + if (ret_b) + *ret_b = b; + else + _gnutls_mpi_release(&b); + + return B; +} + +GNUTLS_MPI _gnutls_calc_srp_u(GNUTLS_MPI B) +{ + int b_size; + opaque *b_holder, hd[MAX_HASH_SIZE]; + GNUTLS_HASH_HANDLE td; + uint32 u; + GNUTLS_MPI ret; + + _gnutls_mpi_print( NULL, &b_size, B); + b_holder = gnutls_malloc(b_size); + if (b_holder==NULL) return NULL; + + _gnutls_mpi_print( b_holder, &b_size, B); + + + td = _gnutls_hash_init(GNUTLS_MAC_SHA); + if (td==NULL) { + gnutls_free(b_holder); + gnutls_assert(); + return NULL; + } + _gnutls_hash(td, b_holder, b_size); + _gnutls_hash_deinit(td, hd); + + memcpy(&u, hd, sizeof(u)); + + gnutls_free(b_holder); + + ret = _gnutls_mpi_set_ui(NULL, u); + if (ret==NULL) { + gnutls_assert(); + return NULL; + } + + return ret; +} + +/* S = (A * v^u) ^ b % N + * this is our shared key + */ +GNUTLS_MPI _gnutls_calc_srp_S1(GNUTLS_MPI A, GNUTLS_MPI b, GNUTLS_MPI u, GNUTLS_MPI v, GNUTLS_MPI n) +{ + GNUTLS_MPI tmp1, tmp2; + GNUTLS_MPI S; + + S = _gnutls_mpi_alloc_like(n); + if (S==NULL) + return NULL; + + tmp1 = _gnutls_mpi_alloc_like(n); + tmp2 = _gnutls_mpi_alloc_like(n); + + if (tmp1 == NULL || tmp2 == NULL) { + _gnutls_mpi_release(&tmp1); + _gnutls_mpi_release(&tmp2); + return NULL; + } + + _gnutls_mpi_powm(tmp1, v, u, n); + _gnutls_mpi_mulm(tmp2, A, tmp1, n); + _gnutls_mpi_release(&tmp1); + + _gnutls_mpi_powm(S, tmp2, b, n); + _gnutls_mpi_release(&tmp2); + + return S; +} + +/* A = g^a % N + * returns A and a (which is random) + */ +GNUTLS_MPI _gnutls_calc_srp_A(GNUTLS_MPI * a, GNUTLS_MPI g, GNUTLS_MPI n) +{ + GNUTLS_MPI tmpa; + GNUTLS_MPI A; + int bits; + + bits = _gnutls_mpi_get_nbits(n); + tmpa = _gnutls_mpi_new(bits); /* FIXME: allocate in secure memory */ + if (tmpa==NULL) { + gnutls_assert(); + return NULL; + } + + _gnutls_mpi_randomize(tmpa, bits, GCRY_STRONG_RANDOM); + + A = _gnutls_mpi_new(bits); /* FIXME: allocate in secure memory */ + if (A==NULL) { + gnutls_assert(); + _gnutls_mpi_release( &tmpa); + return NULL; + } + _gnutls_mpi_powm(A, g, tmpa, n); + + if (a != NULL) + *a = tmpa; + else + _gnutls_mpi_release(&tmpa); + + return A; +} + +/* generate x = SHA(s | SHA(U | ":" | p)) + * The output is exactly 20 bytes + */ +int _gnutls_calc_srp_sha(char *username, char *password, opaque * salt, + int salt_size, int *size, void* digest) +{ + GNUTLS_HASH_HANDLE td; + opaque res[MAX_HASH_SIZE]; + + *size = 20; + + td = _gnutls_hash_init(GNUTLS_MAC_SHA); + if (td==NULL) { + return GNUTLS_E_MEMORY_ERROR; + } + _gnutls_hash(td, username, strlen(username)); + _gnutls_hash(td, ":", 1); + _gnutls_hash(td, password, strlen(password)); + + _gnutls_hash_deinit(td, res); + + td = _gnutls_hash_init(GNUTLS_MAC_SHA); + if (td==NULL) { + return GNUTLS_E_MEMORY_ERROR; + } + + _gnutls_hash(td, salt, salt_size); + _gnutls_hash(td, res, 20); /* 20 bytes is the output of sha1 */ + + _gnutls_hash_deinit(td, digest); + + return 0; +} + +int _gnutls_calc_srp_x(char *username, char *password, opaque * salt, + int salt_size, uint8 crypt_algo, int *size, void* digest) +{ + + switch (crypt_algo) { + case SRPSHA1_CRYPT: + return _gnutls_calc_srp_sha(username, password, salt, + salt_size, size, digest); + case BLOWFISH_CRYPT: + return _gnutls_calc_srp_bcrypt(username, password, salt, salt_size, + size, digest); + } + return -1; +} + + +/* S = (B - g^x) ^ (a + u * x) % N + * this is our shared key + */ +GNUTLS_MPI _gnutls_calc_srp_S2(GNUTLS_MPI B, GNUTLS_MPI g, GNUTLS_MPI x, GNUTLS_MPI a, GNUTLS_MPI u, GNUTLS_MPI n) +{ + GNUTLS_MPI S, tmp1, tmp2, tmp4; + + S = _gnutls_mpi_alloc_like(n); + if (S==NULL) + return NULL; + + tmp1 = _gnutls_mpi_alloc_like(n); + tmp2 = _gnutls_mpi_alloc_like(n); + if (tmp1 == NULL || tmp2 == NULL) { + _gnutls_mpi_release(&tmp1); + _gnutls_mpi_release(&tmp2); + return NULL; + } + + _gnutls_mpi_powm(tmp1, g, x, n); + + _gnutls_mpi_subm(tmp2, B, tmp1, n); + + tmp4 = _gnutls_mpi_alloc_like(n); + if (tmp4==NULL) + return NULL; + + _gnutls_mpi_mul(tmp1, u, x); + _gnutls_mpi_add(tmp4, a, tmp1); + _gnutls_mpi_release(&tmp1); + + _gnutls_mpi_powm(S, tmp2, tmp4, n); + _gnutls_mpi_release(&tmp2); + _gnutls_mpi_release(&tmp4); + + return S; +} + +/** + * gnutls_srp_free_server_sc - Used to free an allocated GNUTLS_SRP_CLIENT_CREDENTIALS structure + * @sc: is an &GNUTLS_SRP_CLIENT_CREDENTIALS structure. + * + * This structure is complex enough to manipulate directly thus + * this helper function is provided in order to free (deallocate) + * the structure. + **/ +void gnutls_srp_free_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS sc) { + gnutls_free( sc->username); + gnutls_free( sc->password); + gnutls_free( sc); +} + +/** + * gnutls_srp_allocate_server_sc - Used to allocate an GNUTLS_SRP_SERVER_CREDENTIALS structure + * @sc: is a pointer to an &GNUTLS_SRP_SERVER_CREDENTIALS structure. + * + * This structure is complex enough to manipulate directly thus + * this helper function is provided in order to allocate + * the structure. + **/ +int gnutls_srp_allocate_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS *sc) { + *sc = gnutls_calloc( 1, sizeof(SRP_CLIENT_CREDENTIALS_INT)); + + if (*sc==NULL) return GNUTLS_E_MEMORY_ERROR; + + return 0; +} + +/** + * gnutls_srp_set_client_cred - Used to set the username/password, in a GNUTLS_SRP_CLIENT_CREDENTIALS structure + * @res: is an &GNUTLS_SRP_CLIENT_CREDENTIALS structure. + * @username: is the user's userid + * @password: is the user's password + * + **/ +int gnutls_srp_set_client_cred( GNUTLS_SRP_CLIENT_CREDENTIALS res, char *username, char * password) { + + if (username==NULL || password == NULL) { + gnutls_assert(); + return GNUTLS_E_INVALID_PARAMETERS; + } + + res->username = gnutls_strdup( username); + if (res->username == NULL) return GNUTLS_E_MEMORY_ERROR; + + res->password = gnutls_strdup( password); + if (res->password==NULL) { + gnutls_free(res->username); + return GNUTLS_E_MEMORY_ERROR; + } + + return 0; +} + +/** + * gnutls_srp_free_server_sc - Used to free an allocated GNUTLS_SRP_SERVER_CREDENTIALS structure + * @sc: is an &GNUTLS_SRP_SERVER_CREDENTIALS structure. + * + * This structure is complex enough to manipulate directly thus + * this helper function is provided in order to free (deallocate) + * the structure. + **/ +void gnutls_srp_free_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS sc) { +int i; + for (i=0;ipassword_files;i++) { + gnutls_free( sc->password_file[i]); + gnutls_free( sc->password_conf_file[i]); + } + gnutls_free(sc->password_file); + gnutls_free(sc->password_conf_file); + + gnutls_free(sc); +} + +/** + * gnutls_srp_allocate_server_sc - Used to allocate an GNUTLS_SRP_SERVER_CREDENTIALS structure + * @sc: is a pointer to an &GNUTLS_SRP_SERVER_CREDENTIALS structure. + * + * This structure is complex enough to manipulate directly thus + * this helper function is provided in order to allocate + * the structure. + **/ +int gnutls_srp_allocate_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS *sc) { + *sc = gnutls_calloc( 1, sizeof(SRP_SERVER_CREDENTIALS_INT)); + + if (*sc==NULL) return GNUTLS_E_MEMORY_ERROR; + + return 0; +} + +inline +static int file_exists( const char* file) { +FILE* fd; + + fd = fopen( file, "r"); + if (fd==NULL) return -1; + + fclose(fd); + return 0; +} + +/** + * gnutls_srp_set_server_cred_file - Used to set the password files, in a GNUTLS_SRP_SERVER_CREDENTIALS structure + * @res: is an &GNUTLS_SRP_SERVER_CREDENTIALS structure. + * @password_file: is the SRP password file (tpasswd) + * @password_conf_file: is the SRP password conf file (tpasswd.conf) + * + **/ +int gnutls_srp_set_server_cred_file( GNUTLS_SRP_SERVER_CREDENTIALS res, char *password_file, char * password_conf_file) { +int i; + + if (password_file==NULL || password_conf_file==NULL) { + gnutls_assert(); + return GNUTLS_E_INVALID_PARAMETERS; + } + + /* Check if the files can be opened */ + if (file_exists( password_file)!=0) { + gnutls_assert(); + return GNUTLS_E_FILE_ERROR; + } + + if (file_exists( password_conf_file)!=0) { + gnutls_assert(); + return GNUTLS_E_FILE_ERROR; + } + + res->password_file = gnutls_realloc( res->password_file, + sizeof(char*)*(res->password_files+1)); + if (res->password_file==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + res->password_conf_file = gnutls_realloc( res->password_conf_file, + sizeof(char*)*(res->password_files+1)); + if (res->password_conf_file==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + i = res->password_files++; + + res->password_file[i] = gnutls_strdup( password_file); + if (res->password_file[i]==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + res->password_conf_file[i] = gnutls_strdup( password_conf_file); + if (res->password_conf_file[i]==NULL) { + gnutls_assert(); + gnutls_free(res->password_file[i]); + return GNUTLS_E_MEMORY_ERROR; + } + + return 0; +} + +/** + * gnutls_srp_server_set_select_func - Used to set a callback to assist in selecting the proper password file + * @state: is a &GNUTLS_STATE structure. + * @func: is the callback function + * + * The callback's function form is: + * int (*callback)(GNUTLS_STATE, const char** pfiles, const char** pconffiles, int npfiles); + * + * 'pfiles' contains 'npfiles' char* structures which hold + * the password file name. 'pconffiles' contain the corresponding + * conf files. + * + * This function specifies what we, in case of a server, are going + * to do when we have to use a password file. If this callback + * function is not provided then gnutls will automaticaly select the + * first password file + * + * In case the callback returned a negative number then gnutls will + * not attempt to choose the appropriate certificate and the caller function + * will fail. + * + * The callback function will only be called once per handshake. + * The callback function should return the index of the certificate + * choosen by the server. -1 indicates an error. + * + **/ +void gnutls_srp_server_set_select_func(GNUTLS_STATE state, + srp_server_select_func + * func) +{ + state->gnutls_internals.server_srp_callback = func; +} + +/** + * gnutls_srp_server_get_username - This function returns the username of the peer + * @state: is a gnutls state + * + * This function will return the username of the peer. This should only be + * called in case of SRP authentication and in case of a server. + * Returns NULL in case of an error. + * + **/ +const char *gnutls_srp_server_get_username(GNUTLS_STATE state) +{ + SRP_SERVER_AUTH_INFO info; + + CHECK_AUTH(GNUTLS_CRD_SRP, NULL); + + info = _gnutls_get_auth_info(state); + if (info == NULL) + return NULL; + return info->username; +} + + +#else /* NO SRP: so define stubs */ + +const char *gnutls_srp_server_get_username(GNUTLS_STATE state) +{ + return NULL; +} + +void gnutls_srp_free_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS sc) { + return; +} + +int gnutls_srp_allocate_client_sc( GNUTLS_SRP_CLIENT_CREDENTIALS *sc) { + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int gnutls_srp_set_client_cred( GNUTLS_SRP_CLIENT_CREDENTIALS res, char *username, char * password) { + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +void gnutls_srp_free_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS sc) { + return; +} + +int gnutls_srp_allocate_server_sc( GNUTLS_SRP_SERVER_CREDENTIALS *sc) { + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +int gnutls_srp_set_server_cred_file( GNUTLS_SRP_SERVER_CREDENTIALS res, char *password_file, char * password_conf_file) { + return GNUTLS_E_UNIMPLEMENTED_FEATURE; +} + +void gnutls_srp_server_set_select_func(GNUTLS_STATE state, + srp_server_select_func + * func) { + return; +} + +#endif /* ENABLE_SRP */ diff --git a/libextra/gnutls_srp.h b/libextra/gnutls_srp.h new file mode 100644 index 0000000000..5f13abd7c1 --- /dev/null +++ b/libextra/gnutls_srp.h @@ -0,0 +1,18 @@ +#ifdef ENABLE_SRP + +int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, MPI g, MPI prime); +MPI _gnutls_calc_srp_B(MPI * ret_b, MPI g, MPI n, MPI v); +MPI _gnutls_calc_srp_u( MPI B); +MPI _gnutls_calc_srp_S1(MPI A, MPI b, MPI u, MPI v, MPI n); +MPI _gnutls_calc_srp_A(MPI *a, MPI g, MPI n); +MPI _gnutls_calc_srp_S2(MPI B, MPI g, MPI x, MPI a, MPI u, MPI n); +int _gnutls_calc_srp_x( char* username, char* password, opaque* salt, int salt_size, uint8 crypt_algo, int* size, void* digest); +int _gnutls_srp_gn( opaque** ret_g, opaque** ret_n, int bits); + +/* our prime */ +extern const uint8 diffie_hellman_group1_prime[130]; + +/* g is defined to be 2 */ +#define SRP_MAX_HASH_SIZE 24 + +#endif -- cgit v1.2.1