diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-10-20 21:41:59 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-10-20 21:44:45 +0200 |
commit | e733486d19f60cb2e7b579cc9f8e7b01625c79a7 (patch) | |
tree | 69b99375d08e501187890f016043ea7a0521d358 /extra | |
parent | 8aad72ed69dbf8150c253de257e3633f1b0070ed (diff) | |
download | gnutls-e733486d19f60cb2e7b579cc9f8e7b01625c79a7.tar.gz |
libgnutls-extra is no more.
Diffstat (limited to 'extra')
-rw-r--r-- | extra/Makefile.am | 72 | ||||
-rw-r--r-- | extra/gnutls-extra.pc.in | 26 | ||||
-rw-r--r-- | extra/gnutls_extra.c | 93 | ||||
-rw-r--r-- | extra/gnutls_openssl.c | 912 | ||||
-rw-r--r-- | extra/includes/Makefile.am | 28 | ||||
-rw-r--r-- | extra/includes/gnutls/openssl.h | 332 | ||||
-rw-r--r-- | extra/libgnutls-extra.map | 32 | ||||
-rw-r--r-- | extra/openssl_compat.c | 172 | ||||
-rw-r--r-- | extra/openssl_compat.h | 37 |
9 files changed, 1704 insertions, 0 deletions
diff --git a/extra/Makefile.am b/extra/Makefile.am new file mode 100644 index 0000000000..7893244ddc --- /dev/null +++ b/extra/Makefile.am @@ -0,0 +1,72 @@ +## Process this file with automake to produce Makefile.in +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +# Free Software Foundation, Inc. +# +# Author: Nikos Mavrogiannopoulos +# +# This file is part of GnuTLS-EXTRA. +# +# GnuTLS-extra is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# GnuTLS-extra 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 GnuTLS-EXTRA; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +ACLOCAL_AMFLAGS = -I ../m4 -I ../gl/m4 + +AM_CFLAGS = $(WERROR_CFLAGS) $(WSTACK_CFLAGS) $(WARN_CFLAGS) +AM_CPPFLAGS = \ + -I$(srcdir)/../gl \ + -I$(builddir)/../lib/includes \ + -I$(srcdir)/../lib/includes \ + -I$(srcdir)/includes \ + -I$(srcdir)/../lib + +if ENABLE_MINITASN1 +AM_CPPFLAGS += -I$(srcdir)/../lib/minitasn1 +endif + +SUBDIRS = includes + +defexecdir = $(bindir) +defexec_DATA = + + +# OpenSSL + +libgnutls_openssl_la_LDFLAGS = -no-undefined + +if ENABLE_OPENSSL +lib_LTLIBRARIES = libgnutls-openssl.la + +libgnutls_openssl_la_SOURCES = gnutls_openssl.c openssl_compat.h \ + openssl_compat.c + +libgnutls_openssl_la_LIBADD = ../gl/libgnu.la $(LIBSOCKET) \ + ../lib/libgnutls.la + +libgnutls_openssl_la_LDFLAGS += -version-info $(LT_SSL_CURRENT):$(LT_SSL_REVISION):$(LT_SSL_AGE) + +if ENABLE_MINITASN1 +libgnutls_openssl_la_LIBADD += ../lib/minitasn1/libminitasn1.la +else +libgnutls_openssl_la_LDFLAGS += $(LTLIBTASN1) +endif + +if HAVE_LD_OUTPUT_DEF +libgnutls_openssl_la_LDFLAGS += \ + -Wl,--output-def,libgnutls-openssl-$(DLL_VERSION).def +defexec_DATA += libgnutls-openssl-$(DLL_VERSION).def +endif +endif + +DISTCLEANFILES = $(defexec_DATA) diff --git a/extra/gnutls-extra.pc.in b/extra/gnutls-extra.pc.in new file mode 100644 index 0000000000..2eb74ae64f --- /dev/null +++ b/extra/gnutls-extra.pc.in @@ -0,0 +1,26 @@ +# Process this file with autoconf to produce a pkg-config metadata file. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008, 2010 Free Software +# Foundation, Inc. +# Author: Simon Josefsson +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: GnuTLS-extra +Description: Additional add-ons for GnuTLS licensed under GPL +URL: http://www.gnu.org/software/gnutls/ +Requires: gnutls +Version: @VERSION@ +Libs: -L${libdir} -lgnutls-extra +Libs.private: @LIBGNUTLS_EXTRA_LIBS@ +Cflags: -I${includedir} diff --git a/extra/gnutls_extra.c b/extra/gnutls_extra.c new file mode 100644 index 0000000000..a7a4b8019a --- /dev/null +++ b/extra/gnutls_extra.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2001, 2004, 2005, 2007, 2008, 2009, 2010 Free Software + * Foundation, Inc. + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GnuTLS-EXTRA. + * + * GnuTLS-extra is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * GnuTLS-extra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <gnutls_int.h> +#include <gnutls_errors.h> +#include <gnutls_extensions.h> +#include <algorithms.h> +#include <gnutls/extra.h> + +#ifdef HAVE_GCRYPT +#include <gcrypt.h> +#endif + +static int _gnutls_init_extra = 0; + +/** + * gnutls_global_init_extra: + * + * This function initializes the global state of gnutls-extra library + * to defaults. + * + * 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. + * + * This function is not thread safe, see the discussion for + * gnutls_global_init() on how to deal with that. + * + * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned, + * otherwise an error code is returned. + **/ +int +gnutls_global_init_extra (void) +{ + /* If the version of libgnutls != version of + * libextra, then do not initialize the library. + * This is because it may break things. + */ + if (strcmp (gnutls_check_version (NULL), VERSION) != 0) + { + return GNUTLS_E_LIBRARY_VERSION_MISMATCH; + } + + _gnutls_init_extra++; + + if (_gnutls_init_extra != 1) + return 0; + + return 0; +} + +/** + * gnutls_extra_check_version: + * @req_version: version string to compare with, or %NULL. + * + * Check GnuTLS Extra Library version. + * + * See %GNUTLS_EXTRA_VERSION for a suitable @req_version string. + * + * Return value: Check that the version of the library is at + * minimum the one given as a string in @req_version and return the + * actual version string of the library; return %NULL if the + * condition is not met. If %NULL is passed to this function no + * check is done and only the version string is returned. + **/ +const char * +gnutls_extra_check_version (const char *req_version) +{ + if (!req_version || strverscmp (req_version, VERSION) <= 0) + return VERSION; + + return NULL; +} diff --git a/extra/gnutls_openssl.c b/extra/gnutls_openssl.c new file mode 100644 index 0000000000..14121da9a8 --- /dev/null +++ b/extra/gnutls_openssl.c @@ -0,0 +1,912 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2008, 2010 Free Software Foundation, + * Inc. + * Copyright (c) 2002 Andrew McDonald <andrew@mcdonald.org.uk> + * + * This file is part of GnuTLS-EXTRA. + * + * GnuTLS-extra is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GnuTLS-extra is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include <gnutls/gnutls.h> +#include <openssl_compat.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "../lib/gnutls_int.h" +#include "../lib/random.h" +#include "../lib/gnutls_hash_int.h" + +/* In win32 X509_NAME is defined in wincrypt.h. + * undefine it to avoid the conflict with openssl.h. + */ +#ifdef X509_NAME +# undef X509_NAME +#endif +#include <gnutls/openssl.h> + +/* Gnulib re-defines shutdown on mingw. We only use it as a variable + name, so restore the original name. */ +#undef shutdown + +/* XXX: See lib/gnutls_int.h. */ +#define GNUTLS_POINTER_TO_INT(_) ((int) GNUTLS_POINTER_TO_INT_CAST (_)) +#define GNUTLS_INT_TO_POINTER(_) ((void*) GNUTLS_POINTER_TO_INT_CAST (_)) + +/* WARNING: Error functions aren't currently thread-safe */ + +static int last_error = 0; + +/* Library initialisation functions */ + +int +SSL_library_init (void) +{ + gnutls_global_init (); + /* NB: we haven't got anywhere to call gnutls_global_deinit() */ + return 1; +} + +void +OpenSSL_add_all_algorithms (void) +{ +} + + +/* SSL_CTX structure handling */ + +SSL_CTX * +SSL_CTX_new (SSL_METHOD * method) +{ + SSL_CTX *ctx; + + ctx = (SSL_CTX *) calloc (1, sizeof (SSL_CTX)); + ctx->method = method; + + return ctx; +} + +void +SSL_CTX_free (SSL_CTX * ctx) +{ + free (ctx->method); + free (ctx); +} + +int +SSL_CTX_set_default_verify_paths (SSL_CTX * ctx) +{ + return 0; +} + +int +SSL_CTX_use_certificate_file (SSL_CTX * ctx, const char *certfile, int type) +{ + ctx->certfile = (char *) calloc (1, strlen (certfile) + 1); + if (!ctx->certfile) + return -1; + memcpy (ctx->certfile, certfile, strlen (certfile)); + + ctx->certfile_type = type; + + return 1; +} + +int +SSL_CTX_use_PrivateKey_file (SSL_CTX * ctx, const char *keyfile, int type) +{ + ctx->keyfile = (char *) calloc (1, strlen (keyfile) + 1); + if (!ctx->keyfile) + return -1; + memcpy (ctx->keyfile, keyfile, strlen (keyfile)); + + ctx->keyfile_type = type; + + return 1; + +} + +void +SSL_CTX_set_verify (SSL_CTX * ctx, int verify_mode, + int (*verify_callback) (int, X509_STORE_CTX *)) +{ + ctx->verify_mode = verify_mode; + ctx->verify_callback = verify_callback; +} + +unsigned long +SSL_CTX_set_options (SSL_CTX * ctx, unsigned long options) +{ + return (ctx->options |= options); +} + +long +SSL_CTX_set_mode (SSL_CTX * ctx, long mode) +{ + return 0; +} + +int +SSL_CTX_set_cipher_list (SSL_CTX * ctx, const char *list) +{ + /* FIXME: ignore this for the moment */ + /* We're going to have to parse the "list" string to do this */ + /* It is a string, which in its simplest form is something like + "DES-CBC3-SHA:IDEA-CBC-MD5", but can be rather more complicated + (see OpenSSL's ciphers(1) manpage for details) */ + + return 1; +} + + +/* SSL_CTX statistics */ + +long +SSL_CTX_sess_number (SSL_CTX * ctx) +{ + return 0; +} + +long +SSL_CTX_sess_connect (SSL_CTX * ctx) +{ + return 0; +} + +long +SSL_CTX_sess_connect_good (SSL_CTX * ctx) +{ + return 0; +} + +long +SSL_CTX_sess_connect_renegotiate (SSL_CTX * ctx) +{ + return 0; +} + +long +SSL_CTX_sess_accept (SSL_CTX * ctx) +{ + return 0; +} + +long +SSL_CTX_sess_accept_good (SSL_CTX * ctx) +{ + return 0; +} + +long +SSL_CTX_sess_accept_renegotiate (SSL_CTX * ctx) +{ + return 0; +} + +long +SSL_CTX_sess_hits (SSL_CTX * ctx) +{ + return 0; +} + +long +SSL_CTX_sess_misses (SSL_CTX * ctx) +{ + return 0; +} + +long +SSL_CTX_sess_timeouts (SSL_CTX * ctx) +{ + return 0; +} + + + +/* SSL structure handling */ + +SSL * +SSL_new (SSL_CTX * ctx) +{ + SSL *ssl; + int err; + + ssl = (SSL *) calloc (1, sizeof (SSL)); + if (!ssl) + return NULL; + + err = gnutls_certificate_allocate_credentials (&ssl->gnutls_cred); + if (err < 0) + { + last_error = err; + free (ssl); + return NULL; + } + + gnutls_init (&ssl->gnutls_state, ctx->method->connend); + + gnutls_priority_set_direct (ssl->gnutls_state, + ctx->method->priority_string, NULL); + + gnutls_credentials_set (ssl->gnutls_state, GNUTLS_CRD_CERTIFICATE, + ssl->gnutls_cred); + if (ctx->certfile) + gnutls_certificate_set_x509_trust_file (ssl->gnutls_cred, + ctx->certfile, + ctx->certfile_type); + if (ctx->keyfile) + gnutls_certificate_set_x509_key_file (ssl->gnutls_cred, + ctx->certfile, ctx->keyfile, + ctx->keyfile_type); + ssl->ctx = ctx; + ssl->verify_mode = ctx->verify_mode; + ssl->verify_callback = ctx->verify_callback; + + ssl->options = ctx->options; + + ssl->rfd = (gnutls_transport_ptr_t) - 1; + ssl->wfd = (gnutls_transport_ptr_t) - 1; + + return ssl; +} + +void +SSL_free (SSL * ssl) +{ + gnutls_certificate_free_credentials (ssl->gnutls_cred); + gnutls_deinit (ssl->gnutls_state); + free (ssl); +} + +void +SSL_load_error_strings (void) +{ +} + +int +SSL_get_error (SSL * ssl, int ret) +{ + if (ret > 0) + return SSL_ERROR_NONE; + + return SSL_ERROR_ZERO_RETURN; +} + +int +SSL_set_fd (SSL * ssl, int fd) +{ + gnutls_transport_set_ptr (ssl->gnutls_state, GNUTLS_INT_TO_POINTER (fd)); + return 1; +} + +int +SSL_set_rfd (SSL * ssl, int fd) +{ + ssl->rfd = GNUTLS_INT_TO_POINTER (fd); + + if (ssl->wfd != (gnutls_transport_ptr_t) - 1) + gnutls_transport_set_ptr2 (ssl->gnutls_state, ssl->rfd, ssl->wfd); + + return 1; +} + +int +SSL_set_wfd (SSL * ssl, int fd) +{ + ssl->wfd = GNUTLS_INT_TO_POINTER (fd); + + if (ssl->rfd != (gnutls_transport_ptr_t) - 1) + gnutls_transport_set_ptr2 (ssl->gnutls_state, ssl->rfd, ssl->wfd); + + return 1; +} + +void +SSL_set_bio (SSL * ssl, BIO * rbio, BIO * wbio) +{ + gnutls_transport_set_ptr2 (ssl->gnutls_state, rbio->fd, wbio->fd); + /* free(BIO); ? */ +} + +void +SSL_set_connect_state (SSL * ssl) +{ +} + +int +SSL_pending (SSL * ssl) +{ + return gnutls_record_check_pending (ssl->gnutls_state); +} + +void +SSL_set_verify (SSL * ssl, int verify_mode, + int (*verify_callback) (int, X509_STORE_CTX *)) +{ + ssl->verify_mode = verify_mode; + ssl->verify_callback = verify_callback; +} + +const X509 * +SSL_get_peer_certificate (SSL * ssl) +{ + const gnutls_datum_t *cert_list; + unsigned int cert_list_size = 0; + + cert_list = gnutls_certificate_get_peers (ssl->gnutls_state, + &cert_list_size); + + return cert_list; +} + +/* SSL connection open/close/read/write functions */ + +int +SSL_connect (SSL * ssl) +{ + X509_STORE_CTX *store; + unsigned int cert_list_size = 0; + int err; + char x_priority[256]; + /* take options into account before connecting */ + + memset (x_priority, 0, sizeof (x_priority)); + if (ssl->options & SSL_OP_NO_TLSv1) + { + snprintf(x_priority, sizeof(x_priority), "%s:-VERS-TLS1.0", ssl->ctx->method->priority_string); + err = gnutls_priority_set_direct(ssl->gnutls_state, x_priority, NULL); + if (err < 0) + { + last_error = err; + return 0; + } + } + + err = gnutls_handshake (ssl->gnutls_state); + ssl->last_error = err; + + if (err < 0) + { + last_error = err; + return 0; + } + + store = (X509_STORE_CTX *) calloc (1, sizeof (X509_STORE_CTX)); + store->ssl = ssl; + store->cert_list = gnutls_certificate_get_peers (ssl->gnutls_state, + &cert_list_size); + + if (ssl->verify_callback) + { + ssl->verify_callback (1 /*FIXME*/, store); + } + ssl->state = SSL_ST_OK; + + err = store->error; + free (store); + + /* FIXME: deal with error from callback */ + + return 1; +} + +int +SSL_accept (SSL * ssl) +{ + X509_STORE_CTX *store; + unsigned int cert_list_size = 0; + int err; + char x_priority[256]; + /* take options into account before connecting */ + + memset (x_priority, 0, sizeof (x_priority)); + if (ssl->options & SSL_OP_NO_TLSv1) + { + snprintf(x_priority, sizeof(x_priority), "%s:-VERS-TLS1.0", ssl->ctx->method->priority_string); + err = gnutls_priority_set_direct(ssl->gnutls_state, x_priority, NULL); + if (err < 0) + { + last_error = err; + return 0; + } + } + + /* FIXME: dh params, do we want client cert? */ + + err = gnutls_handshake (ssl->gnutls_state); + ssl->last_error = err; + + if (err < 0) + { + last_error = err; + return 0; + } + + store = (X509_STORE_CTX *) calloc (1, sizeof (X509_STORE_CTX)); + store->ssl = ssl; + store->cert_list = gnutls_certificate_get_peers (ssl->gnutls_state, + &cert_list_size); + + if (ssl->verify_callback) + { + ssl->verify_callback (1 /*FIXME*/, store); + } + ssl->state = SSL_ST_OK; + + err = store->error; + free (store); + + /* FIXME: deal with error from callback */ + + return 1; +} + +int +SSL_shutdown (SSL * ssl) +{ + if (!ssl->shutdown) + { + gnutls_bye (ssl->gnutls_state, GNUTLS_SHUT_WR); + ssl->shutdown++; + } + else + { + gnutls_bye (ssl->gnutls_state, GNUTLS_SHUT_RDWR); + ssl->shutdown++; + } + + /* FIXME */ + return 1; +} + +int +SSL_read (SSL * ssl, void *buf, int len) +{ + int ret; + + ret = gnutls_record_recv (ssl->gnutls_state, buf, len); + ssl->last_error = ret; + + if (ret < 0) + { + last_error = ret; + return 0; + } + + return ret; +} + +int +SSL_write (SSL * ssl, const void *buf, int len) +{ + int ret; + + ret = gnutls_record_send (ssl->gnutls_state, buf, len); + ssl->last_error = ret; + + if (ret < 0) + { + last_error = ret; + return 0; + } + + return ret; +} + +int +SSL_want (SSL * ssl) +{ + return SSL_NOTHING; +} + + +/* SSL_METHOD functions */ + +SSL_METHOD * +SSLv23_client_method (void) +{ + SSL_METHOD *m; + m = (SSL_METHOD *) calloc (1, sizeof (SSL_METHOD)); + if (!m) + return NULL; + + strcpy(m->priority_string, "NONE:+VERS-TLS1.0:+VERS-SSL3.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL"); + + m->connend = GNUTLS_CLIENT; + + return m; +} + +SSL_METHOD * +SSLv23_server_method (void) +{ + SSL_METHOD *m; + m = (SSL_METHOD *) calloc (1, sizeof (SSL_METHOD)); + if (!m) + return NULL; + + strcpy(m->priority_string, "NONE:+VERS-TLS1.0:+VERS-SSL3.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL"); + m->connend = GNUTLS_SERVER; + + return m; +} + +SSL_METHOD * +SSLv3_client_method (void) +{ + SSL_METHOD *m; + m = (SSL_METHOD *) calloc (1, sizeof (SSL_METHOD)); + if (!m) + return NULL; + + strcpy(m->priority_string, "NONE:+VERS-SSL3.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL"); + m->connend = GNUTLS_CLIENT; + + return m; +} + +SSL_METHOD * +SSLv3_server_method (void) +{ + SSL_METHOD *m; + m = (SSL_METHOD *) calloc (1, sizeof (SSL_METHOD)); + if (!m) + return NULL; + + strcpy(m->priority_string, "NONE:+VERS-SSL3.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL"); + m->connend = GNUTLS_SERVER; + + return m; +} + +SSL_METHOD * +TLSv1_client_method (void) +{ + SSL_METHOD *m; + m = (SSL_METHOD *) calloc (1, sizeof (SSL_METHOD)); + if (!m) + return NULL; + + strcpy(m->priority_string, "NONE:+VERS-TLS1.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL"); + m->connend = GNUTLS_CLIENT; + + return m; +} + +SSL_METHOD * +TLSv1_server_method (void) +{ + SSL_METHOD *m; + m = (SSL_METHOD *) calloc (1, sizeof (SSL_METHOD)); + if (!m) + return NULL; + + strcpy(m->priority_string, "NONE:+VERS-TLS1.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL"); + m->connend = GNUTLS_SERVER; + + return m; +} + + +/* SSL_CIPHER functions */ + +SSL_CIPHER * +SSL_get_current_cipher (SSL * ssl) +{ + if (!ssl) + return NULL; + + ssl->ciphersuite.version = gnutls_protocol_get_version (ssl->gnutls_state); + ssl->ciphersuite.cipher = gnutls_cipher_get (ssl->gnutls_state); + ssl->ciphersuite.kx = gnutls_kx_get (ssl->gnutls_state); + ssl->ciphersuite.mac = gnutls_mac_get (ssl->gnutls_state); + ssl->ciphersuite.compression = gnutls_compression_get (ssl->gnutls_state); + ssl->ciphersuite.cert = gnutls_certificate_type_get (ssl->gnutls_state); + + return &(ssl->ciphersuite); +} + +const char * +SSL_CIPHER_get_name (SSL_CIPHER * cipher) +{ + if (!cipher) + return ("NONE"); + + return gnutls_cipher_suite_get_name (cipher->kx, + cipher->cipher, cipher->mac); +} + +int +SSL_CIPHER_get_bits (SSL_CIPHER * cipher, int *bits) +{ + int bit_result; + + if (!cipher) + return 0; + + bit_result = (8 * gnutls_cipher_get_key_size (cipher->cipher)); + + if (bits) + *bits = bit_result; + + return bit_result; +} + +const char * +SSL_CIPHER_get_version (SSL_CIPHER * cipher) +{ + const char *ret; + + if (!cipher) + return ("(NONE)"); + + ret = gnutls_protocol_get_name (cipher->version); + if (ret) + return ret; + + return ("unknown"); +} + +char * +SSL_CIPHER_description (SSL_CIPHER * cipher, char *buf, int size) +{ + char *tmpbuf; + int tmpsize; + int local_alloc; + + if (buf) + { + tmpbuf = buf; + tmpsize = size; + local_alloc = 0; + } + else + { + tmpbuf = (char *) malloc (128); + tmpsize = 128; + local_alloc = 1; + } + + if (snprintf (tmpbuf, tmpsize, "%s %s %s %s", + gnutls_protocol_get_name (cipher->version), + gnutls_kx_get_name (cipher->kx), + gnutls_cipher_get_name (cipher->cipher), + gnutls_mac_get_name (cipher->mac)) == -1) + { + if (local_alloc) + free (tmpbuf); + return (char *) "Buffer too small"; + } + + return tmpbuf; +} + + +/* X509 functions */ + +X509_NAME * +X509_get_subject_name (const X509 * cert) +{ + gnutls_x509_dn *dn; + dn = (gnutls_x509_dn *) calloc (1, sizeof (gnutls_x509_dn)); + if (gnutls_x509_extract_certificate_dn (cert, dn) < 0) + { + free (dn); + return NULL; + } + return dn; +} + +X509_NAME * +X509_get_issuer_name (const X509 * cert) +{ + gnutls_x509_dn *dn; + dn = (gnutls_x509_dn *) calloc (1, sizeof (gnutls_x509_dn)); + if (gnutls_x509_extract_certificate_issuer_dn (cert, dn) < 0) + { + free (dn); + return NULL; + } + return dn; +} + +char * +X509_NAME_oneline (gnutls_x509_dn * name, char *buf, int len) +{ + /* XXX openssl allocates buffer if buf == NULL */ + if (!buf) + return NULL; + memset (buf, 0, len); + + snprintf (buf, len - 1, + "C=%s, ST=%s, L=%s, O=%s, OU=%s, CN=%s/Email=%s", + name->country, name->state_or_province_name, + name->locality_name, name->organization, + name->organizational_unit_name, name->common_name, name->email); + return buf; +} + +void +X509_free (const X509 * cert) +{ + /* only get certificates as const items */ +} + + +/* BIO functions */ + +void +BIO_get_fd (gnutls_session_t gnutls_state, int *fd) +{ + gnutls_transport_ptr_t tmp = gnutls_transport_get_ptr (gnutls_state); + *fd = GNUTLS_POINTER_TO_INT (tmp); +} + +BIO * +BIO_new_socket (int sock, int close_flag) +{ + BIO *bio; + + bio = (BIO *) malloc (sizeof (BIO)); + if (!bio) + return NULL; + + bio->fd = GNUTLS_INT_TO_POINTER (sock); + + return bio; +} + + +/* error handling */ + +unsigned long +ERR_get_error (void) +{ + unsigned long ret; + + ret = -1 * last_error; + last_error = 0; + + return ret; +} + +const char * +ERR_error_string (unsigned long e, char *buf) +{ + return gnutls_strerror (-1 * e); +} + + +/* RAND functions */ + +int +RAND_status (void) +{ + return 1; +} + +void +RAND_seed (const void *buf, int num) +{ +} + +int +RAND_bytes (unsigned char *buf, int num) +{ + gnutls_rnd (GNUTLS_RND_RANDOM, buf, num); + return 1; +} + +int +RAND_pseudo_bytes (unsigned char *buf, int num) +{ + gnutls_rnd (GNUTLS_RND_NONCE, buf, num); + return 1; +} + +const char * +RAND_file_name (char *buf, size_t len) +{ + return ""; +} + +int +RAND_load_file (const char *name, long maxbytes) +{ + return maxbytes; +} + +int +RAND_write_file (const char *name) +{ + return 0; +} + +int +RAND_egd_bytes (const char *path, int bytes) +{ + /* fake it */ + return bytes; +} + + +/* message digest functions */ + +void +MD5_Init (MD5_CTX * ctx) +{ + ctx->handle = gnutls_malloc (sizeof (digest_hd_st)); + if (!ctx->handle) + abort (); + _gnutls_hash_init (ctx->handle, GNUTLS_DIG_MD5); +} + +void +MD5_Update (MD5_CTX * ctx, const void *buf, int len) +{ + _gnutls_hash (ctx->handle, buf, len); +} + +void +MD5_Final (unsigned char *md, MD5_CTX * ctx) +{ + _gnutls_hash_deinit (ctx->handle, md); + gnutls_free (ctx->handle); +} + +unsigned char * +MD5 (const unsigned char *buf, unsigned long len, unsigned char *md) +{ + if (!md) + return NULL; + + _gnutls_hash_fast (GNUTLS_DIG_MD5, buf, len, md); + + return md; +} + +void +RIPEMD160_Init (RIPEMD160_CTX * ctx) +{ + ctx->handle = gnutls_malloc (sizeof (digest_hd_st)); + if (!ctx->handle) + abort (); + _gnutls_hash_init (ctx->handle, GNUTLS_DIG_RMD160); +} + +void +RIPEMD160_Update (RIPEMD160_CTX * ctx, const void *buf, int len) +{ + _gnutls_hash (ctx->handle, buf, len); +} + +void +RIPEMD160_Final (unsigned char *md, RIPEMD160_CTX * ctx) +{ + _gnutls_hash_deinit (ctx->handle, md); + gnutls_free (ctx->handle); +} + +unsigned char * +RIPEMD160 (const unsigned char *buf, unsigned long len, unsigned char *md) +{ + if (!md) + return NULL; + + _gnutls_hash_fast (GNUTLS_DIG_RMD160, buf, len, md); + + return md; +} diff --git a/extra/includes/Makefile.am b/extra/includes/Makefile.am new file mode 100644 index 0000000000..5db221ff30 --- /dev/null +++ b/extra/includes/Makefile.am @@ -0,0 +1,28 @@ +## Process this file with automake to produce Makefile.in +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 Free +# Software Foundation, Inc. +# +# Author: Nikos Mavrogiannopoulos +# +# This file is part of GnuTLS-EXTRA. +# +# GnuTLS-extra is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# GnuTLS-extra 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 GnuTLS-EXTRA; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +nobase_include_HEADERS = + +if ENABLE_OPENSSL +nobase_include_HEADERS += gnutls/openssl.h +endif diff --git a/extra/includes/gnutls/openssl.h b/extra/includes/gnutls/openssl.h new file mode 100644 index 0000000000..86ae199b02 --- /dev/null +++ b/extra/includes/gnutls/openssl.h @@ -0,0 +1,332 @@ +/* + * Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010 Free Software + * Foundation, Inc. + * Copyright (c) 2002 Andrew McDonald <andrew@mcdonald.org.uk> + * + * This file is part of GnuTLS-EXTRA. + * + * GnuTLS-extra is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * GnuTLS-extra 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 GnuTLS-EXTRA; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +/* WARNING: Error functions aren't currently thread-safe */ + +/* This file contains prototypes about the OpenSSL compatibility layer + * in GnuTLS. GnuTLS is not a complete replacement of OPENSSL so this + * compatibility layer only support limited OpenSSL functionality. + * + * New programs should avoid using this compatibility layer, and use + * the native GnuTLS API directly. + */ + +#ifndef GNUTLS_OPENSSL_H +#define GNUTLS_OPENSSL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <gnutls/gnutls.h> + +/* Extra definitions that do not longer exist in gnutls. + */ +#define GNUTLS_X509_CN_SIZE 256 +#define GNUTLS_X509_C_SIZE 3 +#define GNUTLS_X509_O_SIZE 256 +#define GNUTLS_X509_OU_SIZE 256 +#define GNUTLS_X509_L_SIZE 256 +#define GNUTLS_X509_S_SIZE 256 +#define GNUTLS_X509_EMAIL_SIZE 256 + + typedef struct + { + char common_name[GNUTLS_X509_CN_SIZE]; + char country[GNUTLS_X509_C_SIZE]; + char organization[GNUTLS_X509_O_SIZE]; + char organizational_unit_name[GNUTLS_X509_OU_SIZE]; + char locality_name[GNUTLS_X509_L_SIZE]; + char state_or_province_name[GNUTLS_X509_S_SIZE]; + char email[GNUTLS_X509_EMAIL_SIZE]; + } gnutls_x509_dn; + + +#define OPENSSL_VERSION_NUMBER (0x0090604F) +#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER +#define OPENSSL_VERSION_TEXT ("GNUTLS " GNUTLS_VERSION " ") + +#define SSL_ERROR_NONE (0) +#define SSL_ERROR_SSL (1) +#define SSL_ERROR_WANT_READ (2) +#define SSL_ERROR_WANT_WRITE (3) +#define SSL_ERROR_SYSCALL (5) +#define SSL_ERROR_ZERO_RETURN (6) + +#define SSL_FILETYPE_PEM (GNUTLS_X509_FMT_PEM) + +#define SSL_VERIFY_NONE (0) + +#define SSL_ST_OK (1) + +#define X509_V_ERR_CERT_NOT_YET_VALID (1) +#define X509_V_ERR_CERT_HAS_EXPIRED (2) +#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT (3) + +#define SSL_OP_ALL (0x000FFFFF) +#define SSL_OP_NO_TLSv1 (0x0400000) + +#define SSL_MODE_ENABLE_PARTIAL_WRITE (0x1) +#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER (0x2) +#define SSL_MODE_AUTO_RETRY (0x4) + + typedef gnutls_x509_dn X509_NAME; + typedef gnutls_datum_t X509; + + typedef struct _SSL SSL; + + typedef struct + { + char priority_string[256]; + unsigned int connend; + } SSL_METHOD; + + typedef struct + { + gnutls_protocol_t version; + gnutls_cipher_algorithm_t cipher; + gnutls_kx_algorithm_t kx; + gnutls_mac_algorithm_t mac; + gnutls_compression_method_t compression; + gnutls_certificate_type_t cert; + } SSL_CIPHER; + + typedef struct _BIO + { + gnutls_transport_ptr_t fd; + } BIO; + + typedef struct + { + SSL *ssl; + int error; + const gnutls_datum_t *cert_list; +#define current_cert cert_list + } X509_STORE_CTX; + +#define X509_STORE_CTX_get_current_cert(ctx) ((ctx)->current_cert) + + typedef struct _SSL_CTX + { + SSL_METHOD *method; + char *certfile; + int certfile_type; + char *keyfile; + int keyfile_type; + unsigned long options; + + int (*verify_callback) (int, X509_STORE_CTX *); + int verify_mode; + + } SSL_CTX; + + struct _SSL + { + gnutls_session_t gnutls_state; + + gnutls_certificate_client_credentials gnutls_cred; + + SSL_CTX *ctx; + SSL_CIPHER ciphersuite; + + int last_error; + int shutdown; + int state; + unsigned long options; + + int (*verify_callback) (int, X509_STORE_CTX *); + int verify_mode; + + gnutls_transport_ptr_t rfd; + gnutls_transport_ptr_t wfd; + }; + +#define rbio gnutls_state + + typedef struct + { + void *handle; + } MD_CTX; + + struct rsa_st; + typedef struct rsa_st RSA; + +#define MD5_CTX MD_CTX +#define RIPEMD160_CTX MD_CTX + +#define OpenSSL_add_ssl_algorithms() SSL_library_init() +#define SSLeay_add_ssl_algorithms() SSL_library_init() +#define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms() + +#define SSL_get_cipher_name(ssl) SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)) +#define SSL_get_cipher(ssl) SSL_get_cipher_name(ssl) +#define SSL_get_cipher_bits(ssl,bp) SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl),(bp)) +#define SSL_get_cipher_version(ssl) SSL_CIPHER_get_version(SSL_get_current_cipher(ssl)) + + +/* Library initialisation functions */ + + int SSL_library_init (void); + void OpenSSL_add_all_algorithms (void); + + +/* SSL_CTX structure handling */ + + SSL_CTX *SSL_CTX_new (SSL_METHOD * method); + void SSL_CTX_free (SSL_CTX * ctx); + int SSL_CTX_set_default_verify_paths (SSL_CTX * ctx); + int SSL_CTX_use_certificate_file (SSL_CTX * ctx, const char *certfile, + int type); + int SSL_CTX_use_PrivateKey_file (SSL_CTX * ctx, const char *keyfile, + int type); + void SSL_CTX_set_verify (SSL_CTX * ctx, int verify_mode, + int (*verify_callback) (int, X509_STORE_CTX *)); + unsigned long SSL_CTX_set_options (SSL_CTX * ctx, unsigned long options); + long SSL_CTX_set_mode (SSL_CTX * ctx, long mode); + int SSL_CTX_set_cipher_list (SSL_CTX * ctx, const char *list); + + +/* SSL_CTX statistics */ + + long SSL_CTX_sess_number (SSL_CTX * ctx); + long SSL_CTX_sess_connect (SSL_CTX * ctx); + long SSL_CTX_sess_connect_good (SSL_CTX * ctx); + long SSL_CTX_sess_connect_renegotiate (SSL_CTX * ctx); + long SSL_CTX_sess_accept (SSL_CTX * ctx); + long SSL_CTX_sess_accept_good (SSL_CTX * ctx); + long SSL_CTX_sess_accept_renegotiate (SSL_CTX * ctx); + long SSL_CTX_sess_hits (SSL_CTX * ctx); + long SSL_CTX_sess_misses (SSL_CTX * ctx); + long SSL_CTX_sess_timeouts (SSL_CTX * ctx); + + +/* SSL structure handling */ + + SSL *SSL_new (SSL_CTX * ctx); + void SSL_free (SSL * ssl); + void SSL_load_error_strings (void); + int SSL_get_error (SSL * ssl, int ret); + int SSL_set_fd (SSL * ssl, int fd); + int SSL_set_rfd (SSL * ssl, int fd); + int SSL_set_wfd (SSL * ssl, int fd); + void SSL_set_bio (SSL * ssl, BIO * rbio, BIO * wbio); + void SSL_set_connect_state (SSL * ssl); + int SSL_pending (SSL * ssl); + void SSL_set_verify (SSL * ssl, int verify_mode, + int (*verify_callback) (int, X509_STORE_CTX *)); + const X509 *SSL_get_peer_certificate (SSL * ssl); + +/* SSL connection open/close/read/write functions */ + + int SSL_connect (SSL * ssl); + int SSL_accept (SSL * ssl); + int SSL_shutdown (SSL * ssl); + int SSL_read (SSL * ssl, void *buf, int len); + int SSL_write (SSL * ssl, const void *buf, int len); + + int SSL_want (SSL * ssl); + +#define SSL_NOTHING (1) +#define SSL_WRITING (2) +#define SSL_READING (3) +#define SSL_X509_LOOKUP (4) + +#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +#define SSL_want_read(s) (SSL_want(s) == SSL_READING) +#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) + + +/* SSL_METHOD functions */ + + SSL_METHOD *SSLv23_client_method (void); + SSL_METHOD *SSLv23_server_method (void); + SSL_METHOD *SSLv3_client_method (void); + SSL_METHOD *SSLv3_server_method (void); + SSL_METHOD *TLSv1_client_method (void); + SSL_METHOD *TLSv1_server_method (void); + + +/* SSL_CIPHER functions */ + + SSL_CIPHER *SSL_get_current_cipher (SSL * ssl); + const char *SSL_CIPHER_get_name (SSL_CIPHER * cipher); + int SSL_CIPHER_get_bits (SSL_CIPHER * cipher, int *bits); + const char *SSL_CIPHER_get_version (SSL_CIPHER * cipher); + char *SSL_CIPHER_description (SSL_CIPHER * cipher, char *buf, int size); + + +/* X509 functions */ + + X509_NAME *X509_get_subject_name (const X509 * cert); + X509_NAME *X509_get_issuer_name (const X509 * cert); + char *X509_NAME_oneline (gnutls_x509_dn * name, char *buf, int len); + void X509_free (const X509 * cert); + + +/* BIO functions */ + + void BIO_get_fd (gnutls_session_t gnutls_state, int *fd); + BIO *BIO_new_socket (int sock, int close_flag); + +/* error handling */ + + unsigned long ERR_get_error (void); + const char *ERR_error_string (unsigned long e, char *buf); + + +/* RAND functions */ + + int RAND_status (void); + void RAND_seed (const void *buf, int num); + int RAND_bytes (unsigned char *buf, int num); + int RAND_pseudo_bytes (unsigned char *buf, int num); + const char *RAND_file_name (char *buf, size_t len); + int RAND_load_file (const char *name, long maxbytes); + int RAND_write_file (const char *name); + + int RAND_egd_bytes (const char *path, int bytes); +#define RAND_egd(p) RAND_egd_bytes((p), 255) + +/* message digest functions */ + +#define MD5_DIGEST_LENGTH 16 + + void MD5_Init (MD5_CTX * ctx); + void MD5_Update (MD5_CTX * ctx, const void *buf, int len); + void MD5_Final (unsigned char *md, MD5_CTX * ctx); + unsigned char *MD5 (const unsigned char *buf, unsigned long len, + unsigned char *md); + + void RIPEMD160_Init (RIPEMD160_CTX * ctx); + void RIPEMD160_Update (RIPEMD160_CTX * ctx, const void *buf, int len); + void RIPEMD160_Final (unsigned char *md, RIPEMD160_CTX * ctx); + unsigned char *RIPEMD160 (const unsigned char *buf, unsigned long len, + unsigned char *md); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra/libgnutls-extra.map b/extra/libgnutls-extra.map new file mode 100644 index 0000000000..f0c75046fd --- /dev/null +++ b/extra/libgnutls-extra.map @@ -0,0 +1,32 @@ +# libgnutls-extra.map -- libgnutls-extra linker version script-*- ld-script -*- +# Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# +# Author: Simon Josefsson +# +# This file is part of GnuTLS-EXTRA. +# +# GnuTLS-extra is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# GnuTLS-extra 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 GnuTLS-EXTRA; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +GNUTLS_1_4 +{ + global: + gnutls_extra_check_version; + gnutls_global_init_extra; + + local: + *; +}; diff --git a/extra/openssl_compat.c b/extra/openssl_compat.c new file mode 100644 index 0000000000..4ce4bf0a6f --- /dev/null +++ b/extra/openssl_compat.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2010 Free Software + * Foundation, Inc. + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GnuTLS-EXTRA. + * + * GnuTLS-extra is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GnuTLS-extra is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* This file includes all functions that were in the 0.5.x and 0.8.x + * gnutls API. They are now implemented over the new certificate parsing + * API. + */ + +#include "gnutls_int.h" + +#include <gnutls_global.h> +#include <gnutls_errors.h> +#include <string.h> /* memset */ +#include <x509/x509_int.h> +#include <libtasn1.h> +#include <gnutls/x509.h> +#include <openssl_compat.h> + +/*- + * gnutls_x509_extract_certificate_dn: + * @cert: should contain an X.509 DER encoded certificate + * @ret: a pointer to a structure to hold the peer's name + * + * This function will return the name of the certificate holder. The name is gnutls_x509_dn structure and + * is a obtained by the peer's certificate. If the certificate send by the + * peer is invalid, or in any other failure this function returns error. + * Returns a negative error code in case of an error. + -*/ +int +gnutls_x509_extract_certificate_dn (const gnutls_datum_t * cert, + gnutls_x509_dn * ret) +{ + gnutls_x509_crt_t xcert; + int result; + size_t len; + + result = gnutls_x509_crt_init (&xcert); + if (result < 0) + return result; + + result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER); + if (result < 0) + { + gnutls_x509_crt_deinit (xcert); + return result; + } + + len = sizeof (ret->country); + gnutls_x509_crt_get_dn_by_oid (xcert, GNUTLS_OID_X520_COUNTRY_NAME, 0, + 0, ret->country, &len); + + len = sizeof (ret->organization); + gnutls_x509_crt_get_dn_by_oid (xcert, GNUTLS_OID_X520_ORGANIZATION_NAME, + 0, 0, ret->organization, &len); + + len = sizeof (ret->organizational_unit_name); + gnutls_x509_crt_get_dn_by_oid (xcert, + GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, + 0, 0, ret->organizational_unit_name, &len); + + len = sizeof (ret->common_name); + gnutls_x509_crt_get_dn_by_oid (xcert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, + ret->common_name, &len); + + len = sizeof (ret->locality_name); + gnutls_x509_crt_get_dn_by_oid (xcert, GNUTLS_OID_X520_LOCALITY_NAME, 0, + 0, ret->locality_name, &len); + + len = sizeof (ret->state_or_province_name); + gnutls_x509_crt_get_dn_by_oid (xcert, + GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, + 0, 0, ret->state_or_province_name, &len); + + len = sizeof (ret->email); + gnutls_x509_crt_get_dn_by_oid (xcert, GNUTLS_OID_PKCS9_EMAIL, 0, 0, + ret->email, &len); + + gnutls_x509_crt_deinit (xcert); + + return 0; +} + +/*- + * gnutls_x509_extract_certificate_issuer_dn: + * @cert: should contain an X.509 DER encoded certificate + * @ret: a pointer to a structure to hold the issuer's name + * + * This function will return the name of the issuer stated in the certificate. The name is a gnutls_x509_dn structure and + * is a obtained by the peer's certificate. If the certificate send by the + * peer is invalid, or in any other failure this function returns error. + * Returns a negative error code in case of an error. + -*/ +int +gnutls_x509_extract_certificate_issuer_dn (const gnutls_datum_t * cert, + gnutls_x509_dn * ret) +{ + gnutls_x509_crt_t xcert; + int result; + size_t len; + + result = gnutls_x509_crt_init (&xcert); + if (result < 0) + return result; + + result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER); + if (result < 0) + { + gnutls_x509_crt_deinit (xcert); + return result; + } + + len = sizeof (ret->country); + gnutls_x509_crt_get_issuer_dn_by_oid (xcert, + GNUTLS_OID_X520_COUNTRY_NAME, 0, + 0, ret->country, &len); + + len = sizeof (ret->organization); + gnutls_x509_crt_get_issuer_dn_by_oid (xcert, + GNUTLS_OID_X520_ORGANIZATION_NAME, + 0, 0, ret->organization, &len); + + len = sizeof (ret->organizational_unit_name); + gnutls_x509_crt_get_issuer_dn_by_oid (xcert, + GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, + 0, 0, + ret->organizational_unit_name, &len); + + len = sizeof (ret->common_name); + gnutls_x509_crt_get_issuer_dn_by_oid (xcert, + GNUTLS_OID_X520_COMMON_NAME, 0, 0, + ret->common_name, &len); + + len = sizeof (ret->locality_name); + gnutls_x509_crt_get_issuer_dn_by_oid (xcert, + GNUTLS_OID_X520_LOCALITY_NAME, 0, + 0, ret->locality_name, &len); + + len = sizeof (ret->state_or_province_name); + gnutls_x509_crt_get_issuer_dn_by_oid (xcert, + GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, + 0, 0, ret->state_or_province_name, + &len); + + len = sizeof (ret->email); + gnutls_x509_crt_get_issuer_dn_by_oid (xcert, GNUTLS_OID_PKCS9_EMAIL, 0, + 0, ret->email, &len); + + gnutls_x509_crt_deinit (xcert); + + return 0; +} + + diff --git a/extra/openssl_compat.h b/extra/openssl_compat.h new file mode 100644 index 0000000000..d467ee067e --- /dev/null +++ b/extra/openssl_compat.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2002, 2003, 2004, 2005, 2008, 2010 Free Software + * Foundation, Inc. + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GnuTLS-EXTRA. + * + * GnuTLS-extra is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * GnuTLS-extra 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 GnuTLS-EXTRA; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +#ifndef GNUTLS_COMPAT8_H +#define GNUTLS_COMPAT8_H + +/* Extra definitions */ +#include <gnutls/openssl.h> + +int gnutls_x509_extract_certificate_dn (const gnutls_datum_t *, + gnutls_x509_dn *); +int gnutls_x509_extract_certificate_issuer_dn (const gnutls_datum_t *, + gnutls_x509_dn *); + +#endif |