├── src ├── versioninfo.rc.in ├── ntbtls.pc.in ├── libntbtls.vers ├── libntbtls.def ├── visibility.h ├── visibility.c ├── Makefile.am ├── wipemem.h ├── ntbtls-config.in ├── debug.c ├── util.c ├── util.h ├── ntbtls.m4 ├── ntbtls.h.in ├── dhm.c ├── pkglue.c ├── ciphersuites.h ├── ntbtls-cli.c └── ecdh.c ├── m4 ├── Makefile.am ├── ltversion.m4 ├── ltsugar.m4 ├── lt~obsolete.m4 ├── ksba.m4 ├── gpg-error.m4 ├── libgcrypt.m4 └── ltoptions.m4 ├── README ├── autogen.rc ├── ChangeLog ├── .gitignore ├── AUTHORS ├── README.GIT ├── NEWS ├── doc └── HACKING ├── Makefile.am ├── autogen.sh └── INSTALL /src/versioninfo.rc.in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpg/ntbtls/master/src/versioninfo.rc.in -------------------------------------------------------------------------------- /m4/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | EXTRA_DIST = \ 3 | gpg-error.m4 \ 4 | ksba.m4 \ 5 | libgcrypt.m4 \ 6 | libtool.m4 ltoptions.m4 ltsugar.m4 ltversion.m4 7 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | NTBTLS 2 | Not Too Bad Transport Layer Security 3 | Version 0.3 4 | 5 | See the file AUTHORS for copying conditions. See HACKING for 6 | internals. This library is based on PolarSSL code with all support 7 | for legacy protocol versions removed. TLS 1.3 and the server part are 8 | not yet implemented. NTBTL depends on Libgcrypt and LibKSBA. 9 | -------------------------------------------------------------------------------- /autogen.rc: -------------------------------------------------------------------------------- 1 | # autogen.sh configuration for GnuPG -*- sh -*- 2 | 3 | ersion_parts=3 4 | 5 | case "$myhost:$myhostsub" in 6 | w32:) 7 | extraoptions="" 8 | ;; 9 | esac 10 | 11 | case "$myhost" in 12 | w32) 13 | configure_opts=" 14 | --with-zlib=@SYSROOT@ 15 | " 16 | ;; 17 | esac 18 | 19 | 20 | extra_aclocal_flags= 21 | 22 | final_info="./configure --enable-maintainer-mode && make" 23 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | ChangeLog files are auto-generated 2 | ================================== 3 | 4 | Do not modify any of the ChangeLog files in this project. We put 5 | change information only in the GIT commit log, and generate a 6 | top-level ChangeLog file from logs at "make dist" time. As such, 7 | there are strict requirements on the form of the commit log messages. 8 | See doc/HACKING for details. 9 | 10 | 11 | 12 | Local Variables: 13 | buffer-read-only: t 14 | mode: text 15 | End: 16 | -------------------------------------------------------------------------------- /src/ntbtls.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | includedir=@includedir@ 4 | libdir=@libdir@ 5 | host=@NTBTLS_CONFIG_HOST@ 6 | api_version=@NTBTLS_CONFIG_API_VERSION@ 7 | 8 | Name: ntbtls 9 | Description: The Not Too Bad TLS Library 10 | Requires: gpg-error 11 | Requires.private: ksba, libgcrypt 12 | Version: @PACKAGE_VERSION@ 13 | Cflags: -I${includedir} @NTBTLS_CONFIG_CFLAGS@ 14 | Libs: -L${libdir} @NTBTLS_CONFIG_LIBS@ 15 | Libs.private: @NETLIBS@ 16 | URL: https://www.gnupg.org/software/ntbtls/index.html 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.lo 2 | *.o 3 | .deps/ 4 | .libs/ 5 | /VERSION 6 | /aclocal.m4 7 | /autom4te.cache 8 | /config.h.in 9 | /config.h 10 | /config.log 11 | /config.status 12 | /configure 13 | /libtool 14 | /stamp-h1 15 | /Makefile.in 16 | /Makefile 17 | /aclocal.m4 18 | /config.h.in 19 | /configure 20 | /doc/stamp-vti 21 | /doc/version.texi 22 | /m4/Makefile.in 23 | /src/Makefile.in 24 | /src/ntbtls-cli 25 | /doc/Makefile.in 26 | /tests/Makefile.in 27 | /tests/x509-ca-key.pem 28 | /tests/x509-ca.pem 29 | /tests/x509-server-key.pem 30 | /tests/x509-server.pem 31 | -------------------------------------------------------------------------------- /m4/ltversion.m4: -------------------------------------------------------------------------------- 1 | # ltversion.m4 -- version numbers -*- Autoconf -*- 2 | # 3 | # Copyright (C) 2004 Free Software Foundation, Inc. 4 | # Written by Scott James Remnant, 2004 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # @configure_input@ 11 | 12 | # serial 3337 ltversion.m4 13 | # This file is part of GNU Libtool 14 | 15 | m4_define([LT_PACKAGE_VERSION], [2.4.2]) 16 | m4_define([LT_PACKAGE_REVISION], [1.3337]) 17 | 18 | AC_DEFUN([LTVERSION_VERSION], 19 | [macro_version='2.4.2' 20 | macro_revision='1.3337' 21 | _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) 22 | _LT_DECL(, macro_revision, 0) 23 | ]) 24 | -------------------------------------------------------------------------------- /src/libntbtls.vers: -------------------------------------------------------------------------------- 1 | # libntbtls.vers - What symbols to export -*- std -*- 2 | # Copyright (C) 2014 g10 Code GmbH 3 | # 4 | # This file is part of NTBTLS 5 | # 6 | # NTBTLS is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # NTBTLS is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, see . 18 | # 19 | # NOTE: When adding new functions, please make sure to add them also 20 | # to visibility.{c,h} and libntbtls.def. 21 | 22 | NTBTLS_1.0 { 23 | global: 24 | ntbtls_check_version; 25 | ntbtls_set_debug; 26 | ntbtls_set_log_handler; 27 | 28 | ntbtls_new; 29 | _ntbtls_check_context; 30 | ntbtls_release; 31 | 32 | ntbtls_set_transport; 33 | ntbtls_get_stream; 34 | ntbtls_set_hostname; 35 | ntbtls_get_hostname; 36 | ntbtls_set_verify_cb; 37 | 38 | ntbtls_handshake; 39 | 40 | ntbtls_x509_get_peer_cert; 41 | 42 | ntbtls_get_last_alert; 43 | 44 | local: 45 | *; 46 | }; 47 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Library: NTBTLS 2 | Homepage: https://gnupg.org/related_software/ntbtls/ 3 | Download: https://gnupg.org/ftp/gcrypt/ntbtls/ 4 | Repository: git://git.gnupg.org/ntbtls.git 5 | Maintainer: Werner Koch 6 | Bug reports: https://bugs.gnupg.org 7 | Security related bug reports: 8 | License: GPLv3+ 9 | 10 | NTBTLS is free software. See the file COPYING for copying conditions. 11 | License copyright years may be listed using range notation, e.g., 12 | 2000-2013, indicating that every year in the range, inclusive, is a 13 | copyrightable year that would otherwise be listed individually. 14 | 15 | 16 | List of Copyright holders 17 | ========================= 18 | 19 | Copyright (C) 2006-2014 Brainspark B.V. 20 | Copyright (C) 2014-2022 g10 Code GmbH 21 | 22 | 23 | Authors 24 | ================== 25 | 26 | Werner Koch (g10 Code GmbH) 27 | NIIBE Yutaka 28 | 29 | 30 | 31 | More credits 32 | ============ 33 | 34 | NTBTLS is based on PolarSSL (http://www.polarssl.org) which identified 35 | Paul Bakker as lead maintainer. 36 | Please do not file bug reports to them but to the address given at the 37 | top of this file 38 | 39 | 40 | 41 | This file is free software; as a special exception the author gives 42 | unlimited permission to copy and/or distribute it, with or without 43 | modifications, as long as this notice is preserved. 44 | 45 | This file is distributed in the hope that it will be useful, but 46 | WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 47 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 48 | -------------------------------------------------------------------------------- /src/libntbtls.def: -------------------------------------------------------------------------------- 1 | ; libtnbtls.def - List of symbols to export. 2 | ; Copyright (C) 2014 g10 Code GmbH 3 | ; 4 | ; This file is part of NTBTLS 5 | ; 6 | ; NTBTLS is free software; you can redistribute it and/or modify 7 | ; it under the terms of the GNU General Public License as published by 8 | ; the Free Software Foundation; either version 3 of the License, or 9 | ; (at your option) any later version. 10 | ; 11 | ; NTBTLS is distributed in the hope that it will be useful, 12 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | ; GNU General Public License for more details. 15 | ; 16 | ; You should have received a copy of the GNU General Public License 17 | ; along with this program; if not, see . 18 | ; 19 | ; NOTE: When adding new functions, please make sure to add them also 20 | ; to visibility.{c,h} and libntbtls.vers. 21 | 22 | 23 | EXPORTS 24 | ntbtls_check_version @1 25 | ntbtls_set_debug @2 26 | ntbtls_set_log_handler @3 27 | 28 | ntbtls_new @4 29 | _ntbtls_check_context @5 30 | ntbtls_release @6 31 | 32 | ntbtls_set_transport @7 33 | ntbtls_get_stream @8 34 | ntbtls_set_hostname @9 35 | ntbtls_get_hostname @10 36 | ntbtls_set_verify_cb @11 37 | 38 | ntbtls_handshake @12 39 | 40 | ntbtls_x509_get_peer_cert @13 41 | 42 | ntbtls_get_last_alert @14 43 | 44 | ; END 45 | -------------------------------------------------------------------------------- /README.GIT: -------------------------------------------------------------------------------- 1 | If you are building from GIT, run the script 2 | 3 | ./autogen.sh 4 | 5 | first, to make sure that you have all the necessary maintainer tools 6 | are installed and to build the actual configuration files. If you 7 | have just checked out from GIT, you should add the option "--force" to 8 | autogen.sh so that meta data is noticed by autom4te.cache. Then run 9 | 10 | ./configure --enable-maintainer-mode 11 | 12 | followed by the usual make. 13 | 14 | If autogen.sh complains about insufficient versions of the required 15 | tools, or the tools are not installed, you may use environment 16 | variables to override the default tool names: 17 | 18 | AUTOMAKE_SUFFIX is used as a suffix for all tools from the automake 19 | package. For example 20 | AUTOMAKE_SUFFIX="-1.7" ./autogen.sh 21 | uses "automake-1.7" and "aclocal-1.7. 22 | AUTOMAKE_PREFIX is used as a prefix for all tools from the automake 23 | page and may be combined with AUTOMAKE_SUFFIX. e.g.: 24 | AUTOMAKE_PREFIX=/usr/foo/bin ./autogen.sh 25 | uses "automake" and "aclocal" in the /usr/foo/bin 26 | directory. 27 | AUTOCONF_SUFFIX is used as a suffix for all tools from the automake 28 | package 29 | AUTOCONF_PREFIX is used as a prefix for all tools from the automake 30 | package 31 | GETTEXT_SUFFIX is used as a suffix for all tools from the gettext 32 | package 33 | GETTEXT_PREFIX is used as a prefix for all tools from the gettext 34 | package 35 | 36 | It is also possible to use the variable name AUTOMAKE, AUTOCONF, 37 | ACLOCAL, AUTOHEADER, GETTEXT and MSGMERGE to directly specify the name 38 | of the programs to run. It is however better to use the suffix and 39 | prefix forms as described above because that does not require 40 | knowledge about the actual tools used by autogen.sh. 41 | 42 | 43 | Please don't use autopoint, libtoolize or autoreconf unless you are 44 | the current maintainer and want to update the standard configuration 45 | files. All those files should be in GIT and only updated manually 46 | if the maintainer decides that newer versions are required. The 47 | maintainer should also make sure that the required version of automake 48 | et al. are properly indicated at the top of configure.ac and take care 49 | to copy the files and not merely use symlinks. 50 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | Noteworthy changes in version 0.3.3 (unreleased) [C1/A1/R_] 2 | ------------------------------------------------ 3 | 4 | 5 | Noteworthy changes in version 0.3.2 (2024-01-12) [C1/A1/R3] 6 | ------------------------------------------------ 7 | 8 | * Allow server's use of SHA256 hash with secpr384 key. [T6059] 9 | 10 | * Modernize the build scripts. 11 | 12 | Release-info: https://dev.gnupg.org/T6925 13 | 14 | 15 | Noteworthy changes in version 0.3.1 (2022-04-07) [C1/A1/R2] 16 | ------------------------------------------------ 17 | 18 | * Support ephemeral ECDSA cipher suites. [rT08c1622944] 19 | 20 | * Do not install ntbtls-config if the new gpgrt-config is available. 21 | 22 | 23 | Noteworthy changes in version 0.3.0 (2022-02-07) [C1/A1/R1] 24 | ------------------------------------------------ 25 | 26 | * Support for X448 and X25519 when build with Libgcrypt 1.9 or later. 27 | 28 | * Updates to the build system. 29 | 30 | * Build fixes for macOS. [T5440,T5601] 31 | 32 | 33 | Noteworthy changes in version 0.2.0 (2020-08-27) [C1/A1/R0] 34 | ------------------------------------------------ 35 | 36 | * Add support for ciphersuites using GCM. 37 | 38 | * New function to return alert messages. 39 | 40 | * Improvements to the build system. 41 | 42 | * Interface changes relative to version 0.1.2 43 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 44 | ntbtls_get_last_alert NEW function. 45 | 46 | 47 | Noteworthy changes in version 0.1.2 (2017-09-19) [C0/A0/R2] 48 | ------------------------------------------------ 49 | 50 | * Add support for secp384r1, secp521r1, and 3 Brainpool curves. 51 | 52 | 53 | Noteworthy changes in version 0.1.1 (2017-03-16) [C0/A0/R1] 54 | ------------------------------------------------ 55 | 56 | * Now supports ECDHE-RSA key exchange. 57 | 58 | 59 | Noteworthy changes in version 0.1.0 (2017-02-21) [C0/A0/R0] 60 | ------------------------------------------------ 61 | 62 | * Initial experimental release with only the client code. 63 | 64 | 65 | See the file AUTHORS for copying conditions. 66 | 67 | This file is free software; as a special exception the author gives 68 | unlimited permission to copy and/or distribute it, with or without 69 | modifications, as long as this notice is preserved. 70 | 71 | This file is distributed in the hope that it will be useful, but 72 | WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 73 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 74 | -------------------------------------------------------------------------------- /doc/HACKING: -------------------------------------------------------------------------------- 1 | # HACKING -*- org -*- 2 | #+TITLE: Hacking on NTBTLS 3 | #+TEXT: Some notes on NTBTLS internals 4 | #+STARTUP: showall 5 | #+OPTIONS: ^:{} 6 | 7 | 8 | 9 | ** How to start a GNUTLS test server 10 | 11 | To test the client it is best to test against a different 12 | implementation. GNUTLS is one of the major TLS implementations; 13 | testing against OpenSSL would be useful too - see below. 14 | 15 | #+begin_example 16 | cd ntbls/tests 17 | gnutls-serv --http --x509cafile x509-ca.pem \ 18 | --x509keyfile x509-server-key.pem --x509certfile x509-server.pem \ 19 | --port 8443 20 | #+end_example 21 | 22 | To test only a single ECDHDE cipher suite, this can be useful: 23 | 24 | #+begin_example 25 | --priority SECURE128:+ECDHE-RSA:-RSA:-DHE-RSA:-PSK:-CAMELLIA-128-CBC:\ 26 | -CAMELLIA-256-CBC:-CAMELLIA-256-GCM:-CAMELLIA-128-GCM:-SHA1:\ 27 | -AES-128-GCM:-AES-256-GCM:-SHA384 28 | #+end_example 29 | 30 | 31 | ** How to start an OpenSSL test server 32 | 33 | 34 | * Specs 35 | ** RFC Notes 36 | 37 | *** 4492 - Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer 38 | Security (TLS). S. Blake-Wilson, N. Bolyard, V. Gupta, C. Hawk, B. 39 | Moeller. May 2006. (Format: TXT=72231 bytes) (Updated by RFC5246, 40 | RFC7027) (Status: INFORMATIONAL) (DOI: 10.17487/RFC4492) 41 | 42 | - 5246 :: See A.7 for the changes. 43 | - 7027 :: Brainpool curves 44 | 45 | *** 5246 - The Transport Layer Security (TLS) Protocol Version 1.2. 46 | T. Dierks, E. Rescorla. August 2008. (Format: TXT=222395 bytes) 47 | (Obsoletes RFC3268, RFC4346, RFC4366) (Updates RFC4492) (Updated 48 | by RFC5746, RFC5878, RFC6176) (Status: PROPOSED STANDARD) 49 | 50 | *** 5746 Transport Layer Security (TLS) Renegotiation Indication Extension. 51 | E. Rescorla, M. Ray, S. Dispensa, N. Oskov. February 2010. 52 | (Format: TXT=33790 bytes) (Updates RFC5246, RFC4366, RFC4347, 53 | RFC4346, RFC2246) (Status: PROPOSED STANDARD) 54 | 55 | *** 5878 Transport Layer Security (TLS) Authorization Extensions. 56 | M. Brown, R. Housley. May 2010. (Format: TXT=44594 bytes) (Updates 57 | RFC5246) (Status: EXPERIMENTAL) 58 | 59 | *** 6176 Prohibiting Secure Sockets Layer (SSL) Version 2.0. 60 | S. Turner, T. Polk. March 2011. (Format: TXT=7642 bytes) (Updates 61 | RFC2246, RFC4346, RFC5246) (Status: PROPOSED STANDARD) 62 | 63 | *** 5077 Transport Layer Security (TLS) Session Resumption without 64 | Server-Side State. J. Salowey, H. Zhou, P. Eronen, H. Tschofenig. 65 | January 2008. (Format: TXT=41989 bytes) (Obsoletes RFC4507) 66 | (Status: PROPOSED STANDARD) 67 | -------------------------------------------------------------------------------- /src/visibility.h: -------------------------------------------------------------------------------- 1 | /* visibility.c - Public API 2 | * Copyright (C) 2014 g10 Code GmbH 3 | * 4 | * This file is part of NTBTLS 5 | * 6 | * NTBTLS is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * NTBTLS is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, see . 18 | */ 19 | 20 | #ifndef NTBTLS_VISIBILITY_H 21 | #define NTBTLS_VISIBILITY_H 22 | 23 | #ifdef _NTBTLS_INCLUDED_BY_VISIBILITY_C 24 | # include "ntbtls-int.h" 25 | #endif 26 | 27 | /* Our use of the ELF visibility feature works by passing 28 | -fvisibiliy=hidden on the command line and by explicitly marking 29 | all exported functions as visible. 30 | 31 | NOTE: When adding new functions, please make sure to add them to 32 | libntbtls.vers and libntbtls.def as well. */ 33 | 34 | #ifdef _NTBTLS_INCLUDED_BY_VISIBILITY_C 35 | 36 | /* A macro to flag a function as visible. */ 37 | #ifdef NTBTLS_USE_VISIBILITY 38 | # define MARK_VISIBLE(name) \ 39 | extern __typeof__ (name) name __attribute__ ((visibility("default"))); 40 | #else 41 | # define MARK_VISIBLE(name) /* */ 42 | #endif 43 | 44 | MARK_VISIBLE (ntbtls_check_version) 45 | MARK_VISIBLE (ntbtls_set_debug) 46 | MARK_VISIBLE (ntbtls_set_log_handler) 47 | MARK_VISIBLE (ntbtls_new) 48 | MARK_VISIBLE (_ntbtls_check_context) 49 | MARK_VISIBLE (ntbtls_release) 50 | MARK_VISIBLE (ntbtls_set_transport) 51 | MARK_VISIBLE (ntbtls_get_stream) 52 | MARK_VISIBLE (ntbtls_set_hostname) 53 | MARK_VISIBLE (ntbtls_get_hostname) 54 | MARK_VISIBLE (ntbtls_handshake) 55 | MARK_VISIBLE (ntbtls_set_verify_cb) 56 | MARK_VISIBLE (ntbtls_x509_get_peer_cert) 57 | MARK_VISIBLE (ntbtls_get_last_alert) 58 | 59 | 60 | #undef MARK_VISIBLE 61 | 62 | #else /*!_NTBTLS_INCLUDED_BY_VISIBILITY_C*/ 63 | 64 | /* To avoid accidental use of the public functions inside ntbtls, 65 | we redefine them to catch such errors. */ 66 | 67 | #define ntbtls_check_version _ntbtls_USE_THE_UNDERSCORED_FUNCTION 68 | #define ntbtls_set_debug _ntbtls_USE_THE_UNDERSCORED_FUNCTION 69 | #define ntbtls_set_log_handler _ntbtls_USE_THE_UNDERSCORED_FUNCTION 70 | #define ntbtls_new _ntbtls_USE_THE_UNDERSCORED_FUNCTION 71 | #define ntbtls_released _ntbtls_USE_THE_UNDERSCORED_FUNCTION 72 | #define ntbtls_set_transport _ntbtls_USE_THE_UNDERSCORED_FUNCTION 73 | #define ntbtls_get_stream _ntbtls_USE_THE_UNDERSCORED_FUNCTION 74 | #define ntbtls_set_hostname _ntbtls_USE_THE_UNDERSCORED_FUNCTION 75 | #define ntbtls_get_hostname _ntbtls_USE_THE_UNDERSCORED_FUNCTION 76 | #define ntbtls_handshake _ntbtls_USE_THE_UNDERSCORED_FUNCTION 77 | #define ntbtls_set_verify_cb _ntbtls_USE_THE_UNDERSCORED_FUNCTION 78 | #define ntbtls_x509_get_peer_cert _ntbtls_USE_THE_UNDERSCORED_FUNCTION 79 | #define ntbtls_get_last_alert _ntbtls_USE_THE_UNDERSCORED_FUNCTION 80 | 81 | #endif /*!_NTBTLS_INCLUDED_BY_VISIBILITY_C*/ 82 | #endif /*NTBTLS_VISIBILITY_H*/ 83 | -------------------------------------------------------------------------------- /src/visibility.c: -------------------------------------------------------------------------------- 1 | /* visibility.c - Public API 2 | * Copyright (C) 2014 g10 Code GmbH 3 | * 4 | * This file is part of NTBTLS 5 | * 6 | * NTBTLS is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * NTBTLS is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #define _NTBTLS_INCLUDED_BY_VISIBILITY_C 24 | #include "visibility.h" 25 | 26 | 27 | const char * 28 | ntbtls_check_version (const char *req_version) 29 | { 30 | return _ntbtls_check_version (req_version); 31 | } 32 | 33 | 34 | void 35 | ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream) 36 | { 37 | _ntbtls_set_debug (level, prefix, stream); 38 | } 39 | 40 | 41 | void 42 | ntbtls_set_log_handler (ntbtls_log_handler_t cb, void *cb_value) 43 | { 44 | _ntbtls_set_log_handler (cb, cb_value); 45 | } 46 | 47 | 48 | gpg_error_t 49 | ntbtls_new (ntbtls_t *r_tls, unsigned int flags) 50 | { 51 | return _ntbtls_new (r_tls, flags); 52 | } 53 | 54 | 55 | /* Check that TLS is valid. FILE and LINE are printed in case of a 56 | * failure. Returns True on failure. This should be called using the 57 | * corresponding macro. */ 58 | gpg_error_t 59 | _ntbtls_check_context (ntbtls_t tls, const char *file, int line) 60 | { 61 | if (!tls || tls->magic != NTBTLS_CONTEXT_MAGIC) 62 | { 63 | _ntbtls_debug_bug (file, line); 64 | return gpg_error (GPG_ERR_BUG); 65 | } 66 | return 0; 67 | } 68 | 69 | 70 | void 71 | ntbtls_release (ntbtls_t tls) 72 | { 73 | _ntbtls_release (tls); 74 | } 75 | 76 | 77 | gpg_error_t 78 | ntbtls_set_transport (ntbtls_t tls, 79 | gpgrt_stream_t inbound, gpgrt_stream_t outbound) 80 | { 81 | return _ntbtls_set_transport (tls, inbound, outbound); 82 | } 83 | 84 | 85 | gpg_error_t 86 | ntbtls_get_stream (ntbtls_t tls, 87 | gpgrt_stream_t *r_readfp, gpgrt_stream_t *r_writefp) 88 | { 89 | return _ntbtls_get_stream (tls, r_readfp, r_writefp); 90 | } 91 | 92 | 93 | gpg_error_t 94 | ntbtls_set_hostname (ntbtls_t tls, const char *hostname) 95 | { 96 | return _ntbtls_set_hostname (tls, hostname); 97 | } 98 | 99 | 100 | const char * 101 | ntbtls_get_hostname (ntbtls_t tls) 102 | { 103 | return _ntbtls_get_hostname (tls); 104 | } 105 | 106 | 107 | gpg_error_t 108 | ntbtls_handshake (ntbtls_t tls) 109 | { 110 | return _ntbtls_handshake (tls); 111 | } 112 | 113 | 114 | const char * 115 | ntbtls_get_last_alert (ntbtls_t tls, 116 | unsigned int *r_level, unsigned int *r_type) 117 | { 118 | return _ntbtls_get_last_alert (tls, r_level, r_type); 119 | } 120 | 121 | 122 | gpg_error_t 123 | ntbtls_set_verify_cb (ntbtls_t tls, ntbtls_verify_cb_t cb, void *cb_value) 124 | { 125 | return _ntbtls_set_verify_cb (tls, cb, cb_value); 126 | } 127 | 128 | ksba_cert_t 129 | ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx) 130 | { 131 | return _ntbtls_x509_get_peer_cert (tls, idx); 132 | } 133 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | # src/Makefile.am - for NTBTLS 2 | # Copyright (C) 2014 g10 Code GmbH 3 | # 4 | # This file is part of NTBTLS 5 | # 6 | # NTBTLS is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # NTBTLS is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, see . 18 | 19 | ## Process this file with automake to produce Makefile.in 20 | 21 | pkgconfigdir = $(libdir)/pkgconfig 22 | pkgconfig_DATA = ntbtls.pc 23 | 24 | EXTRA_DIST = ntbtls.h.in ntbtls.m4 libntbtls.vers libntbtls.def \ 25 | versioninfo.rc.in ntbtls.pc.in 26 | if USE_GPGRT_CONFIG 27 | noinst_SCRIPTS = ntbtls-config 28 | else 29 | bin_SCRIPTS = ntbtls-config 30 | endif 31 | include_HEADERS = ntbtls.h 32 | lib_LTLIBRARIES = libntbtls.la 33 | noinst_PROGRAMS = ntbtls-cli 34 | 35 | m4datadir = $(datadir)/aclocal 36 | m4data_DATA = ntbtls.m4 37 | 38 | AM_CPPFLAGS = 39 | AM_CFLAGS = $(GPG_ERROR_CFLAGS) $(KSBA_CFLAGS) $(LIBGCRYPT_CFLAGS) 40 | 41 | if HAVE_LD_VERSION_SCRIPT 42 | libntbtls_version_script_cmd = -Wl,--version-script=$(srcdir)/libntbtls.vers 43 | else 44 | libntbtls_version_script_cmd = 45 | endif 46 | 47 | 48 | if HAVE_W32_SYSTEM 49 | RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ 50 | $(libntbtls_la_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) 51 | LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) 52 | 53 | SUFFIXES = .rc .lo 54 | 55 | .rc.lo: 56 | $(LTRCCOMPILE) -i "$<" -o "$@" 57 | 58 | ntbtls_res = versioninfo.lo 59 | no_undefined = -no-undefined 60 | export_symbols = -export-symbols $(srcdir)/libntbtls.def 61 | 62 | install-def-file: 63 | $(INSTALL) $(srcdir)/libntbtls.def $(DESTDIR)$(libdir)/libntbtls.def 64 | 65 | uninstall-def-file: 66 | -rm $(DESTDIR)$(libdir)/libntbtls.def 67 | 68 | ntbtls_deps = $(ntbtls_res) libntbtls.def 69 | 70 | else !HAVE_W32_SYSTEM 71 | ntbtls_res = 72 | no_undefined = 73 | export_symbols = 74 | ntbtls_deps = 75 | install-def-file: 76 | uninstall-def-file: 77 | endif !HAVE_W32_SYSTEM 78 | 79 | 80 | libntbtls_la_LDFLAGS = $(no_undefined) $(export_symbols) \ 81 | $(libntbtls_version_script_cmd) -version-info \ 82 | @LIBNTBTLS_LT_CURRENT@:@LIBNTBTLS_LT_REVISION@:@LIBNTBTLS_LT_AGE@ 83 | libntbtls_la_INCLUDES = -I$(top_srcdir)/lib 84 | libntbtls_la_DEPENDENCIES = $(srcdir)/libntbtls.vers $(ntbtls_deps) 85 | libntbtls_la_LIBADD = $(ntbtls_res) $(LTLIBOBJS) $(LIBGCRYPT_LIBS) \ 86 | $(KSBA_LIBS) $(GPG_ERROR_LIBS) 87 | 88 | 89 | libntbtls_la_SOURCES = \ 90 | ntbtls.h \ 91 | visibility.c visibility.h \ 92 | context.h ntbtls-int.h wipemem.h \ 93 | util.c util.h \ 94 | protocol.c \ 95 | protocol-cli.c \ 96 | ciphersuites.c ciphersuites.h \ 97 | pkglue.c x509.c dhm.c ecdh.c \ 98 | debug.c 99 | 100 | # protocol-srv.c 101 | 102 | install-data-local: install-def-file 103 | 104 | uninstall-local: uninstall-def-file 105 | 106 | 107 | # Sample programs 108 | 109 | ntbtls_cli_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) $(GPG_ERROR_CFLAGS) 110 | if HAVE_W32_SYSTEM 111 | ntbtls_cli_LDFLAGS = -no-fast-install 112 | else 113 | ntbtls_cli_LDFLAGS = -no-install 114 | endif 115 | ntbtls_cli_LDADD = libntbtls.la $(LIBGCRYPT_LIBS) $(KSBA_LIBS) \ 116 | $(GPG_ERROR_LIBS) $(NETLIBS) 117 | -------------------------------------------------------------------------------- /src/wipemem.h: -------------------------------------------------------------------------------- 1 | /* wipemem.h - wipememory macros 2 | * Copyright (C) 2013 Jussi Kivilinna 3 | * Copyright (C) 2014 g10 Code GmbH 4 | * 5 | * This file is part of NTBTLS 6 | * 7 | * NTBTLS is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * NTBTLS is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, see . 19 | */ 20 | 21 | #ifndef NTBTLS_WIPEMEM_H 22 | #define NTBTLS_WIPEMEM_H 23 | 24 | /* To avoid that a compiler optimizes certain memset calls away, these 25 | macros may be used instead. */ 26 | #ifdef HAVE_STDINT_H 27 | # include 28 | 29 | /* Following architectures can handle unaligned accesses fast. */ 30 | # if defined(__i386__) || defined(__x86_64__) || \ 31 | defined(__powerpc__) || defined(__powerpc64__) || \ 32 | (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \ 33 | defined(__aarch64__) 34 | # define _fast_wipememory2_unaligned_head(_ptr,_set,_len) /*do nothing*/ 35 | # else 36 | #define FASTWIPE_T uint64_t 37 | # define _fast_wipememory2_unaligned_head(_vptr,_vset,_vlen) do \ 38 | { \ 39 | while((size_t)(_vptr)&(sizeof(FASTWIPE_T)-1) && _vlen) \ 40 | { *_vptr=(_vset); _vptr++; _vlen--; } \ 41 | } while(0) 42 | # endif 43 | 44 | /* _fast_wipememory2 may leave tail bytes unhandled, in which case 45 | tail bytes are handled by wipememory2. */ 46 | # define _fast_wipememory2(_vptr,_vset,_vlen) do \ 47 | { \ 48 | uint64_t _vset_long = _vset; \ 49 | _fast_wipememory2_unaligned_head(_vptr,_vset,_vlen); \ 50 | if (_vlen < sizeof(uint64_t)) \ 51 | break; \ 52 | _vset_long *= UINT64_C(0x0101010101010101); \ 53 | do { \ 54 | volatile uint64_t *_vptr_long = (volatile void *)_vptr; \ 55 | *_vptr_long = _vset_long; \ 56 | _vlen -= sizeof(uint64_t); \ 57 | _vptr += sizeof(uint64_t); \ 58 | } while (_vlen >= sizeof(uint64_t)); \ 59 | } while (0) 60 | 61 | 62 | # define wipememory2(_ptr,_set,_len) do \ 63 | { \ 64 | volatile char *_vptr=(volatile char *)(_ptr); \ 65 | size_t _vlen=(_len); \ 66 | unsigned char _vset=(_set); \ 67 | _fast_wipememory2(_vptr,_vset,_vlen); \ 68 | while(_vlen) { *_vptr=(_vset); _vptr++; _vlen--; } \ 69 | } while (0) 70 | 71 | #else /*!HAVE_STDINT_H*/ 72 | 73 | # define wipememory2(_ptr,_set,_len) do \ 74 | { \ 75 | volatile char *_vptr=(volatile char *)(_ptr); \ 76 | size_t _vlen=(_len); \ 77 | while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \ 78 | } while (0) 79 | 80 | 81 | #endif /*!HAVE_STDINT_H*/ 82 | 83 | #define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) 84 | 85 | #endif /*NTBTLS_WIPEMEM_H*/ 86 | -------------------------------------------------------------------------------- /src/ntbtls-config.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright (C) 1999, 2002, 2003, 2004, 2011 Free Software Foundation, Inc. 3 | # 4 | # This file is free software; as a special exception the author gives 5 | # unlimited permission to copy and/or distribute it, with or without 6 | # modifications, as long as this notice is preserved. 7 | # 8 | # This file is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | # 12 | # File: @configure_input@ 13 | 14 | # General. 15 | prefix="@prefix@" 16 | exec_prefix="@exec_prefix@" 17 | version="@PACKAGE_VERSION@" 18 | includedir="@includedir@" 19 | libdir="@libdir@" 20 | gpg_error_libs="@GPG_ERROR_LIBS@" 21 | gpg_error_cflags="@GPG_ERROR_CFLAGS@" 22 | 23 | # libgcrypt values. 24 | libs="@NTBTLS_CONFIG_LIBS@ -lksba -lgcrypt" 25 | cflags="@NTBTLS_CONFIG_CFLAGS@" 26 | 27 | # API info 28 | api_version="@NTBTLS_CONFIG_API_VERSION@" 29 | 30 | # Configured for host 31 | my_host="@NTBTLS_CONFIG_HOST@" 32 | 33 | # Misc information. 34 | 35 | # State variables. 36 | echo_libs=no 37 | echo_cflags=no 38 | echo_prefix=no 39 | echo_exec_prefix=no 40 | echo_version=no 41 | echo_api_version=no 42 | echo_host=no 43 | 44 | # Prints usage information. 45 | usage() 46 | { 47 | cat <&2 64 | fi 65 | 66 | while test $# -gt 0; do 67 | case "$1" in 68 | # Set up `optarg'. 69 | --*=*) 70 | optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` 71 | ;; 72 | *) 73 | optarg="" 74 | ;; 75 | esac 76 | 77 | case $1 in 78 | --thread=*) 79 | echo "$0: --thread option obsolete: use the thread callback interface" 1>&2 80 | exit 1 81 | ;; 82 | --prefix=*) 83 | # For compatibility reasons with old M4 macros, we ignore 84 | # setting of prefix. 85 | ;; 86 | --prefix) 87 | echo_prefix=yes 88 | ;; 89 | --exec-prefix=*) 90 | ;; 91 | --exec-prefix) 92 | echo_exec_prefix=yes 93 | ;; 94 | --variable=*) 95 | case "${1#*=}" in 96 | prefix) echo "$prefix" ;; 97 | exec_prefix) echo "$exec_prefix" ;; 98 | host) echo "$my_host" ;; 99 | api_version) echo "$api_version" ;; 100 | esac 101 | exit 0 102 | ;; 103 | --modversion|--version) 104 | echo_version=yes 105 | ;; 106 | --api-version) 107 | echo_api_version=yes 108 | ;; 109 | --cflags) 110 | echo_cflags=yes 111 | ;; 112 | --libs) 113 | echo_libs=yes 114 | ;; 115 | --host) 116 | echo_host=yes 117 | ;; 118 | *) 119 | usage 1 1>&2 120 | ;; 121 | esac 122 | shift 123 | done 124 | 125 | if test "$echo_prefix" = "yes"; then 126 | echo "$prefix" 127 | fi 128 | 129 | if test "$echo_exec_prefix" = "yes"; then 130 | echo "$exec_prefix" 131 | fi 132 | 133 | if test "$echo_cflags" = "yes"; then 134 | includes="" 135 | cflags_final="$cflags" 136 | 137 | # Set up `includes'. 138 | if test "x$includedir" != "x/usr/include" -a "x$includedir" != "x/include"; then 139 | includes="-I$includedir" 140 | fi 141 | # Set up `cflags_final'. 142 | cflags_final="$cflags_final $gpg_error_cflags" 143 | 144 | tmp="" 145 | for i in $includes $cflags_final; do 146 | if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then 147 | tmp="$tmp $i" 148 | fi 149 | done 150 | echo $tmp 151 | fi 152 | 153 | if test "$echo_libs" = "yes"; then 154 | libdirs="" 155 | libs_final="$libs" 156 | 157 | # Set up `libdirs'. 158 | if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/lib"; then 159 | libdirs="-L$libdir" 160 | fi 161 | 162 | # Set up `libs_final'. 163 | libs_final="$libs_final $gpg_error_libs" 164 | 165 | tmp="" 166 | for i in $libdirs $libs_final; do 167 | if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then 168 | tmp="$tmp $i" 169 | fi 170 | done 171 | echo $tmp 172 | fi 173 | 174 | if test "$echo_version" = "yes"; then 175 | echo "$version" 176 | fi 177 | 178 | if test "$echo_api_version" = "yes"; then 179 | echo "$api_version" 180 | fi 181 | 182 | if test "$echo_host" = "yes"; then 183 | echo "$my_host" 184 | fi 185 | -------------------------------------------------------------------------------- /m4/ltsugar.m4: -------------------------------------------------------------------------------- 1 | # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- 2 | # 3 | # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. 4 | # Written by Gary V. Vaughan, 2004 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # serial 6 ltsugar.m4 11 | 12 | # This is to help aclocal find these macros, as it can't see m4_define. 13 | AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) 14 | 15 | 16 | # lt_join(SEP, ARG1, [ARG2...]) 17 | # ----------------------------- 18 | # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their 19 | # associated separator. 20 | # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier 21 | # versions in m4sugar had bugs. 22 | m4_define([lt_join], 23 | [m4_if([$#], [1], [], 24 | [$#], [2], [[$2]], 25 | [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) 26 | m4_define([_lt_join], 27 | [m4_if([$#$2], [2], [], 28 | [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) 29 | 30 | 31 | # lt_car(LIST) 32 | # lt_cdr(LIST) 33 | # ------------ 34 | # Manipulate m4 lists. 35 | # These macros are necessary as long as will still need to support 36 | # Autoconf-2.59 which quotes differently. 37 | m4_define([lt_car], [[$1]]) 38 | m4_define([lt_cdr], 39 | [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], 40 | [$#], 1, [], 41 | [m4_dquote(m4_shift($@))])]) 42 | m4_define([lt_unquote], $1) 43 | 44 | 45 | # lt_append(MACRO-NAME, STRING, [SEPARATOR]) 46 | # ------------------------------------------ 47 | # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. 48 | # Note that neither SEPARATOR nor STRING are expanded; they are appended 49 | # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). 50 | # No SEPARATOR is output if MACRO-NAME was previously undefined (different 51 | # than defined and empty). 52 | # 53 | # This macro is needed until we can rely on Autoconf 2.62, since earlier 54 | # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. 55 | m4_define([lt_append], 56 | [m4_define([$1], 57 | m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) 58 | 59 | 60 | 61 | # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) 62 | # ---------------------------------------------------------- 63 | # Produce a SEP delimited list of all paired combinations of elements of 64 | # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list 65 | # has the form PREFIXmINFIXSUFFIXn. 66 | # Needed until we can rely on m4_combine added in Autoconf 2.62. 67 | m4_define([lt_combine], 68 | [m4_if(m4_eval([$# > 3]), [1], 69 | [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl 70 | [[m4_foreach([_Lt_prefix], [$2], 71 | [m4_foreach([_Lt_suffix], 72 | ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, 73 | [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) 74 | 75 | 76 | # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) 77 | # ----------------------------------------------------------------------- 78 | # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited 79 | # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. 80 | m4_define([lt_if_append_uniq], 81 | [m4_ifdef([$1], 82 | [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], 83 | [lt_append([$1], [$2], [$3])$4], 84 | [$5])], 85 | [lt_append([$1], [$2], [$3])$4])]) 86 | 87 | 88 | # lt_dict_add(DICT, KEY, VALUE) 89 | # ----------------------------- 90 | m4_define([lt_dict_add], 91 | [m4_define([$1($2)], [$3])]) 92 | 93 | 94 | # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) 95 | # -------------------------------------------- 96 | m4_define([lt_dict_add_subkey], 97 | [m4_define([$1($2:$3)], [$4])]) 98 | 99 | 100 | # lt_dict_fetch(DICT, KEY, [SUBKEY]) 101 | # ---------------------------------- 102 | m4_define([lt_dict_fetch], 103 | [m4_ifval([$3], 104 | m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), 105 | m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) 106 | 107 | 108 | # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) 109 | # ----------------------------------------------------------------- 110 | m4_define([lt_if_dict_fetch], 111 | [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], 112 | [$5], 113 | [$6])]) 114 | 115 | 116 | # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) 117 | # -------------------------------------------------------------- 118 | m4_define([lt_dict_filter], 119 | [m4_if([$5], [], [], 120 | [lt_join(m4_quote(m4_default([$4], [[, ]])), 121 | lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), 122 | [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl 123 | ]) 124 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile - for NTBTLS 2 | # Copyright (C) 2014 g10 Code GmbH 3 | # 4 | # This file is part of NTBTLS 5 | # 6 | # NTBTLS is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # NTBTLS is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, see . 18 | 19 | ## Process this file with automake to produce Makefile.in 20 | 21 | # Location of the released tarball archives. This is prefixed by 22 | # the variable RELEASE_ARCHIVE in ~/.gnupg-autogen.rc. For example: 23 | # RELEASE_ARCHIVE=wk@somehost:archive/tarballs 24 | RELEASE_ARCHIVE_SUFFIX = ntbtls 25 | 26 | ACLOCAL_AMFLAGS = -I m4 27 | DISTCHECK_CONFIGURE_FLAGS = 28 | 29 | # (A suitable gitlog-to-changelog script can be found in GnuPG master.) 30 | GITLOG_TO_CHANGELOG=gitlog-to-changelog 31 | 32 | DIST_SUBDIRS = m4 src 33 | SUBDIRS = src 34 | 35 | EXTRA_DIST = autogen.sh autogen.rc README.GIT VERSION \ 36 | build-aux/git-log-footer build-aux/git-log-fix \ 37 | build-aux/libtool-patch.sed 38 | 39 | DISTCLEANFILES = 40 | 41 | dist-hook: gen-ChangeLog 42 | 43 | distcheck-hook: 44 | set -e; ( \ 45 | pref="#+macro: ntbtls_" ;\ 46 | reldate="$$(date -u +%Y-%m-%d)" ;\ 47 | echo "$${pref}ver $(PACKAGE_VERSION)" ;\ 48 | echo "$${pref}date $${reldate}" ;\ 49 | list='$(DIST_ARCHIVES)'; for i in $$list; do \ 50 | case "$$i" in *.tar.bz2) \ 51 | echo "$${pref}size $$(wc -c <$$i|awk '{print int($$1/1024)}')k" ;\ 52 | echo "$${pref}sha1 $$(sha1sum <$$i|cut -d' ' -f1)" ;\ 53 | echo "$${pref}sha2 $$(sha256sum <$$i|cut -d' ' -f1)" ;;\ 54 | esac;\ 55 | done ) | tee $(distdir).swdb 56 | 57 | 58 | .PHONY: gen-ChangeLog 59 | gen-ChangeLog: 60 | if test -d $(top_srcdir)/.git; then \ 61 | (cd $(top_srcdir) && \ 62 | $(GITLOG_TO_CHANGELOG) --append-dot --tear-off \ 63 | --amend=build-aux/git-log-fix \ 64 | ) > $(distdir)/cl-t; \ 65 | cat $(top_srcdir)/build-aux/git-log-footer >> $(distdir)/cl-t;\ 66 | rm -f $(distdir)/ChangeLog; \ 67 | mv $(distdir)/cl-t $(distdir)/ChangeLog; \ 68 | fi 69 | 70 | 71 | 72 | .PHONY: gen-ChangeLog clean-coverage coverage-html release sign-release 73 | 74 | # Macro to help the release target. 75 | RELEASE_NAME = $(PACKAGE_TARNAME)-$(PACKAGE_VERSION) 76 | 77 | release: 78 | +(set -e;\ 79 | if [ "$(abs_top_builddir)" = "$(abs_top_srcdir)" ]; then \ 80 | echo "error: build directory must not be the source directory" >&2;\ 81 | exit 2;\ 82 | fi ;\ 83 | echo "/* Build started at $$(date -uIseconds) */" ;\ 84 | cd $(top_srcdir); \ 85 | ./autogen.sh --force; \ 86 | cd $(abs_top_builddir); \ 87 | rm -rf dist; mkdir dist ; cd dist ; \ 88 | $(abs_top_srcdir)/configure --enable-maintainer-mode; \ 89 | $(MAKE) distcheck; \ 90 | echo "/* Build finished at $$(date -uIseconds) */" ;\ 91 | echo "/*" ;\ 92 | echo " * Please run the final step interactivly:" ;\ 93 | echo " * make sign-release" ;\ 94 | echo " */" ;\ 95 | ) 2>&1 | tee "$(RELEASE_NAME).buildlog" 96 | 97 | sign-release: 98 | +(set -e; \ 99 | test $$(pwd | sed 's,.*/,,') = dist || cd dist; \ 100 | x=$$(grep '^RELEASE_ARCHIVE=' $$HOME/.gnupg-autogen.rc|cut -d= -f2);\ 101 | if [ -z "$$x" ]; then \ 102 | echo "error: RELEASE_ARCHIVE missing in ~/.gnupg-autogen.rc">&2; \ 103 | exit 2;\ 104 | fi;\ 105 | myarchive="$$x/$(RELEASE_ARCHIVE_SUFFIX)";\ 106 | x=$$(grep '^RELEASE_SIGNKEY=' $$HOME/.gnupg-autogen.rc|cut -d= -f2);\ 107 | if [ -z "$$x" ]; then \ 108 | echo "error: RELEASE_SIGNKEY missing in ~/.gnupg-autogen.rc">&2; \ 109 | exit 2;\ 110 | fi;\ 111 | mysignkey="$$x";\ 112 | files1="$(RELEASE_NAME).tar.bz2" ; \ 113 | files2="$(RELEASE_NAME).tar.bz2.sig \ 114 | $(RELEASE_NAME).swdb \ 115 | $(RELEASE_NAME).buildlog" ;\ 116 | echo "/* Signing the source tarball ..." ;\ 117 | gpg -sbu $$mysignkey $(RELEASE_NAME).tar.bz2 ;\ 118 | cat $(RELEASE_NAME).swdb >swdb.snippet;\ 119 | echo >>swdb.snippet ;\ 120 | sha1sum $${files1} >>swdb.snippet ;\ 121 | cat "../$(RELEASE_NAME).buildlog" swdb.snippet \ 122 | | gzip >$(RELEASE_NAME).buildlog ;\ 123 | echo "Copying to archive $$myarchive ..." ;\ 124 | scp -p $${files1} $${files2} $${myarchive}/ || true;\ 125 | echo '/*' ;\ 126 | echo ' * All done; for checksums see dist/swdb.snippet' ;\ 127 | echo ' */' ;\ 128 | ) 129 | -------------------------------------------------------------------------------- /src/debug.c: -------------------------------------------------------------------------------- 1 | /* debug.c - Debug functions 2 | * Copyright (C) 2014 g10 Code GmbH 3 | * 4 | * This file is part of NTBTLS 5 | * 6 | * NTBTLS is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * NTBTLS is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "ntbtls-int.h" 26 | 27 | static int debug_level; 28 | static const char *debug_prefix; 29 | static estream_t debug_stream; 30 | static ntbtls_log_handler_t log_handler; 31 | static void *log_handler_value; 32 | 33 | 34 | /* Set the Debug level up to which debug messages are shown. 0 35 | * disables debug messages except for those which will always be 36 | * shown. PREFIX is prefix to prefix all output; the default is 37 | * "ntbtls". STREAM is the output stream; the default is es_stderr. 38 | * Changing STREAM and PREFIX is not thread-safe and their values are 39 | * ignored if a log handler has been set. */ 40 | void 41 | _ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream) 42 | { 43 | static char *debug_prefix_buffer; 44 | 45 | if (!debug_prefix) 46 | debug_prefix = "ntbtls"; 47 | 48 | if (prefix) 49 | { 50 | free (debug_prefix_buffer); 51 | debug_prefix_buffer = malloc (strlen (prefix)); 52 | if (debug_prefix_buffer) 53 | debug_prefix = debug_prefix_buffer; 54 | } 55 | 56 | debug_stream = stream? stream : es_stderr; 57 | 58 | debug_level = level > 0? level : 0; 59 | } 60 | 61 | 62 | /* Set a dedicated log handler. See the description of 63 | * ntbtls_log_handler_t for details. This is not thread-safe. */ 64 | void 65 | _ntbtls_set_log_handler (ntbtls_log_handler_t cb, void *cb_value) 66 | { 67 | log_handler = cb; 68 | log_handler_value = cb_value; 69 | } 70 | 71 | 72 | /* Note that a LEVEL of -1 will always print even when debugging has 73 | * not been enabled. */ 74 | void 75 | _ntbtls_debug_msg (int level, const char *format, ...) 76 | { 77 | va_list arg_ptr; 78 | int saved_errno; 79 | int no_lf; 80 | 81 | if (level != -1 && (!debug_level || level > debug_level)) 82 | return; 83 | 84 | va_start (arg_ptr, format); 85 | saved_errno = errno; 86 | if (log_handler) 87 | { 88 | log_handler (log_handler_value, level, format, arg_ptr); 89 | } 90 | else 91 | { 92 | if ((no_lf = (*format == '\b'))) 93 | format++; 94 | 95 | gpgrt_fputs ("ntbtls: ", es_stderr); 96 | gpgrt_vfprintf (es_stderr, format, arg_ptr); 97 | if (no_lf) 98 | gpgrt_fflush (es_stderr); /* To sync with stderr. */ 99 | else if (*format && format[strlen(format)-1] != '\n') 100 | gpgrt_fputc ('\n', es_stderr); 101 | } 102 | 103 | va_end (arg_ptr); 104 | gpg_err_set_errno (saved_errno); 105 | } 106 | 107 | 108 | void 109 | _ntbtls_debug_bug (const char *file, int line) 110 | { 111 | const char *s; 112 | 113 | s = strrchr (file, '/'); 114 | if (s) 115 | file = s + 1; 116 | _ntbtls_debug_msg (-1, "bug detected at %s:%d\n", file, line); 117 | } 118 | 119 | 120 | void 121 | _ntbtls_debug_ret (int level, const char *name, gpg_error_t err) 122 | { 123 | if (!debug_level || level > debug_level) 124 | return; 125 | 126 | if (err) 127 | _ntbtls_debug_msg (level, "%s returned: %s <%s>\n", 128 | name, gpg_strerror (err), gpg_strsource (err)); 129 | else 130 | _ntbtls_debug_msg (level, "%s returned: success\n", name); 131 | } 132 | 133 | 134 | void 135 | _ntbtls_debug_buf (int level, const char *text, const void *buf, size_t len) 136 | { 137 | if (!debug_level || level > debug_level) 138 | return; 139 | 140 | gcry_log_debughex (text, buf, len); 141 | } 142 | 143 | 144 | void 145 | _ntbtls_debug_mpi (int level, const char *text, gcry_mpi_t a) 146 | { 147 | if (!debug_level || level > debug_level) 148 | return; 149 | 150 | gcry_log_debugmpi (text, a); 151 | } 152 | 153 | 154 | void 155 | _ntbtls_debug_pnt (int level, const char *text, 156 | gcry_mpi_point_t a, gcry_ctx_t ctx) 157 | { 158 | if (!debug_level || level > debug_level) 159 | return; 160 | 161 | gcry_log_debugpnt (text, a, ctx); 162 | } 163 | 164 | 165 | void 166 | _ntbtls_debug_sxp (int level, const char *text, gcry_sexp_t a) 167 | { 168 | if (!debug_level || level > debug_level) 169 | return; 170 | 171 | gcry_log_debugsxp (text, a); 172 | } 173 | 174 | 175 | void 176 | _ntbtls_debug_crt (int level, const char *text, x509_cert_t chain) 177 | { 178 | if (!debug_level || level > debug_level) 179 | return; 180 | 181 | _ntbtls_x509_log_cert (text, chain, (debug_level > 1)); 182 | } 183 | -------------------------------------------------------------------------------- /src/util.c: -------------------------------------------------------------------------------- 1 | /* util.c - Utility functions 2 | * Copyright (C) 2014 g10 Code GmbH 3 | * 4 | * This file is part of NTBTLS 5 | * 6 | * NTBTLS is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * NTBTLS is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "ntbtls-int.h" 27 | 28 | 29 | const char * 30 | compat_identification (void) 31 | { 32 | /* For a complete list of copyright holders see the file AUTHORS in 33 | the source distribution. */ 34 | static const char blurb[] = 35 | "\n\n" 36 | "This is NTBTLS " PACKAGE_VERSION " - Not Too Bad TLS\n" 37 | "Copyright (C) 2014-2022 g10 Code GmbH\n" 38 | "Copyright (C) 2006-2014 Brainspark B.V.\n" 39 | "\n" 40 | "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n" 41 | "\n\n"; 42 | return blurb; 43 | } 44 | 45 | 46 | /* Version number parsing. */ 47 | 48 | /* This function parses the first portion of the version number S and 49 | stores it in *NUMBER. On success, this function returns a pointer 50 | into S starting with the first character, which is not part of the 51 | initial number portion; on failure, NULL is returned. */ 52 | static const char* 53 | parse_version_number (const unsigned char *s, int *number) 54 | { 55 | int val = 0; 56 | 57 | if (*s == '0' && isdigit(s[1])) 58 | return NULL; /* Leading zeros are not allowed. */ 59 | for ( ; isdigit (*s); s++) 60 | { 61 | val *= 10; 62 | val += *s - '0'; 63 | } 64 | *number = val; 65 | return val < 0? NULL : s; 66 | } 67 | 68 | 69 | /* This function breaks up the complete string representation of the 70 | version number S, which is of the following structure: 71 | 72 | .. 73 | 74 | The major, minor and micro number components will be stored in 75 | *MAJOR, *MINOR and *MICRO. 76 | 77 | On success, the last component, the patch level, will be returned; 78 | in failure, NULL will be returned. */ 79 | 80 | static const char * 81 | parse_version_string (const char *s, int *major, int *minor, int *micro ) 82 | { 83 | s = parse_version_number (s, major); 84 | if (!s || *s != '.') 85 | return NULL; 86 | s++; 87 | s = parse_version_number (s, minor); 88 | if (!s || *s != '.') 89 | return NULL; 90 | s++; 91 | s = parse_version_number (s, micro); 92 | return s; /* Patchlevel or NULL on error in MICRO. */ 93 | } 94 | 95 | 96 | /* If REQ_VERSION is non-NULL, check that the version of the library 97 | is at minimum the requested one. Returns the string representation 98 | of the library version if the condition is satisfied; return NULL 99 | if the requested version is newer than that of the library. 100 | 101 | If a NULL is passed to this function, no check is done, but the 102 | string representation of the library version is returned. */ 103 | const char * 104 | _ntbtls_check_version (const char *req_version) 105 | { 106 | const char *ver = PACKAGE_VERSION; 107 | int my_major, my_minor, my_micro; 108 | int rq_major, rq_minor, rq_micro; 109 | const char *my_plvl; 110 | 111 | if (req_version && req_version[0] == 1 && req_version[1] == 1) 112 | return compat_identification (); 113 | 114 | /* Initialize library. */ 115 | 116 | /* Check whether the caller only want the version number. */ 117 | if (!req_version) 118 | return ver; 119 | 120 | /* Parse own version number. */ 121 | my_plvl = parse_version_string (ver, &my_major, &my_minor, &my_micro); 122 | if (!my_plvl) 123 | return NULL; /* Can't happen. */ 124 | 125 | /* Parse requested version number. */ 126 | if (!parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro)) 127 | return NULL; /* Req version string is invalid. */ 128 | 129 | /* Compare version numbers. */ 130 | if (my_major > rq_major 131 | || (my_major == rq_major && my_minor > rq_minor) 132 | || (my_major == rq_major && my_minor == rq_minor && my_micro > rq_micro) 133 | || (my_major == rq_major && my_minor == rq_minor 134 | && my_micro == rq_micro)) 135 | { 136 | return ver; /* Okay. */ 137 | } 138 | 139 | return NULL; /* Not sufficent. */ 140 | } 141 | 142 | 143 | /* 144 | * Remove trailing white spaces from STRING. Returns STRING. 145 | */ 146 | char * 147 | _ntbtls_trim_trailing_spaces (char *string) 148 | { 149 | char *p, *mark; 150 | 151 | for (mark = NULL, p = string; *p; p++ ) 152 | { 153 | if (isspace (*(unsigned char*)p)) 154 | { 155 | if (!mark) 156 | mark = p; 157 | } 158 | else 159 | mark = NULL; 160 | } 161 | if (mark) 162 | *mark = 0; 163 | 164 | return string; 165 | } 166 | 167 | 168 | static inline int 169 | ascii_toupper (int c) 170 | { 171 | if (c >= 'a' && c <= 'z') 172 | c &= ~0x20; 173 | return c; 174 | } 175 | 176 | int 177 | _ntbtls_ascii_strcasecmp (const char *a, const char *b) 178 | { 179 | if (a == b) 180 | return 0; 181 | 182 | for (; *a && *b; a++, b++) 183 | { 184 | if (*a != *b && ascii_toupper (*a) != ascii_toupper (*b)) 185 | break; 186 | } 187 | return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); 188 | } 189 | -------------------------------------------------------------------------------- /m4/lt~obsolete.m4: -------------------------------------------------------------------------------- 1 | # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- 2 | # 3 | # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. 4 | # Written by Scott James Remnant, 2004. 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # serial 5 lt~obsolete.m4 11 | 12 | # These exist entirely to fool aclocal when bootstrapping libtool. 13 | # 14 | # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) 15 | # which have later been changed to m4_define as they aren't part of the 16 | # exported API, or moved to Autoconf or Automake where they belong. 17 | # 18 | # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN 19 | # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us 20 | # using a macro with the same name in our local m4/libtool.m4 it'll 21 | # pull the old libtool.m4 in (it doesn't see our shiny new m4_define 22 | # and doesn't know about Autoconf macros at all.) 23 | # 24 | # So we provide this file, which has a silly filename so it's always 25 | # included after everything else. This provides aclocal with the 26 | # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything 27 | # because those macros already exist, or will be overwritten later. 28 | # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 29 | # 30 | # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. 31 | # Yes, that means every name once taken will need to remain here until 32 | # we give up compatibility with versions before 1.7, at which point 33 | # we need to keep only those names which we still refer to. 34 | 35 | # This is to help aclocal find these macros, as it can't see m4_define. 36 | AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) 37 | 38 | m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) 39 | m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) 40 | m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) 41 | m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) 42 | m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) 43 | m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) 44 | m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) 45 | m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) 46 | m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) 47 | m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) 48 | m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) 49 | m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) 50 | m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) 51 | m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) 52 | m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) 53 | m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) 54 | m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) 55 | m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) 56 | m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) 57 | m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) 58 | m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) 59 | m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) 60 | m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) 61 | m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) 62 | m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) 63 | m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) 64 | m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) 65 | m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) 66 | m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) 67 | m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) 68 | m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) 69 | m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) 70 | m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) 71 | m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) 72 | m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) 73 | m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) 74 | m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) 75 | m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) 76 | m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) 77 | m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) 78 | m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) 79 | m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) 80 | m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) 81 | m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) 82 | m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) 83 | m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) 84 | m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) 85 | m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) 86 | m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) 87 | m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) 88 | m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) 89 | m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) 90 | m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) 91 | m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) 92 | m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) 93 | m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) 94 | m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) 95 | m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) 96 | m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) 97 | m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) 98 | m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) 99 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | /* util.h - Utility functions 2 | * Copyright (C) 2014 g10 Code GmbH 3 | * 4 | * This file is part of NTBTLS 5 | * 6 | * NTBTLS is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * NTBTLS is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, see . 18 | */ 19 | 20 | #ifndef NTBTLS_UTIL_H 21 | #define NTBTLS_UTIL_H 22 | 23 | #include "wipemem.h" 24 | 25 | /* Some handy macros */ 26 | #ifndef STR 27 | #define STR(v) #v 28 | #endif 29 | #define STR2(v) STR(v) 30 | #define DIM(v) (sizeof(v)/sizeof((v)[0])) 31 | #define DIMof(type,member) DIM(((type *)0)->member) 32 | 33 | /* Macros to replace ctype macros so o avoid locale problems. */ 34 | #define spacep(p) (*(p) == ' ' || *(p) == '\t') 35 | #define digitp(p) (*(p) >= '0' && *(p) <= '9') 36 | #define alphap(p) ((*(p) >= 'A' && *(p) <= 'Z') \ 37 | || (*(p) >= 'a' && *(p) <= 'z')) 38 | #define alnump(p) (alphap (p) || digitp (p)) 39 | #define hexdigitp(a) (digitp (a) \ 40 | || (*(a) >= 'A' && *(a) <= 'F') \ 41 | || (*(a) >= 'a' && *(a) <= 'f')) 42 | /* Note this isn't identical to a C locale isspace() without \f and 43 | \v, but works for the purposes used here. */ 44 | #define ascii_isspace(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t') 45 | 46 | /* The atoi macros assume that the buffer has only valid digits. */ 47 | #define atoi_1(p) (*(p) - '0' ) 48 | #define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) 49 | #define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) 50 | #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ 51 | *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) 52 | #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) 53 | #define xtoi_4(p) ((xtoi_2(p) * 256) + xtoi_2((p)+2)) 54 | 55 | 56 | /* Return the size of a OID string without the nul. */ 57 | /* FIXME: Do we use it? */ 58 | #define OID_SIZE(x) (sizeof(x) - 1) 59 | 60 | 61 | /* 62 | * Object to hold X.509 certificates. 63 | */ 64 | struct x509_cert_s; 65 | typedef struct x509_cert_s *x509_cert_t; 66 | 67 | 68 | /* Constant-time compare of two buffers. Returns 0 if buffers are 69 | equal, and 1 if buffers differ. At most places this function can 70 | be used as a memcmp replacement. However, -1 will never be 71 | returned, thus it can't be used for sorting etc. */ 72 | static inline int 73 | memcmpct (const void *_a, const void *_b, size_t len) 74 | { 75 | const unsigned char *a = _a; 76 | const unsigned char *b = _b; 77 | size_t diff, i; 78 | 79 | /* Constant-time compare. */ 80 | for (i = 0, diff = 0; i < len; i++) 81 | diff -= !!(a[i] - b[i]); 82 | 83 | return !!diff; 84 | } 85 | 86 | 87 | /* Buffer to integer functions. */ 88 | 89 | static inline unsigned int 90 | buf16_to_uint (const void *buffer) 91 | { 92 | const unsigned char *p = buffer; 93 | 94 | return (((unsigned int)p[0] << 8) | p[1]); 95 | } 96 | 97 | static inline size_t 98 | buf16_to_size_t (const void *buffer) 99 | { 100 | const unsigned char *p = buffer; 101 | 102 | return (((size_t)p[0] << 8) | p[1]); 103 | } 104 | 105 | static inline size_t 106 | buf24_to_size_t (const void *buffer) 107 | { 108 | const unsigned char *p = buffer; 109 | 110 | return (((size_t)p[0] << 16) | (p[1] << 8) | p[1]); 111 | } 112 | 113 | static inline uint32_t 114 | buf32_to_u32 (const void *buffer) 115 | { 116 | const unsigned char *p = buffer; 117 | 118 | return (((uint32_t)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); 119 | } 120 | 121 | 122 | 123 | 124 | /*-- debug.c --*/ 125 | void _ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream); 126 | void _ntbtls_set_log_handler (ntbtls_log_handler_t cb, void *cb_value); 127 | 128 | void _ntbtls_debug_msg (int level, const char *format, 129 | ...) GPGRT_ATTR_PRINTF(2,3); 130 | void _ntbtls_debug_buf (int level, const char *text, 131 | const void *buf, size_t len); 132 | void _ntbtls_debug_bug (const char *file, int line); 133 | void _ntbtls_debug_ret (int level, const char *name, gpg_error_t err); 134 | void _ntbtls_debug_mpi (int level, const char *text, gcry_mpi_t a); 135 | void _ntbtls_debug_pnt (int level, const char *text, 136 | gcry_mpi_point_t a, gcry_ctx_t ctx); 137 | void _ntbtls_debug_sxp (int level, const char *text, gcry_sexp_t a); 138 | void _ntbtls_debug_crt (int level, const char *text, x509_cert_t chain); 139 | 140 | #define debug_msg _ntbtls_debug_msg 141 | #define debug_buf(a,b,c,d) _ntbtls_debug_buf ((a),(b),(c),(d)) 142 | #define debug_bug() _ntbtls_debug_bug (__FILE__, __LINE__) 143 | #define debug_ret(l,n,e) _ntbtls_debug_ret ((l),(n),(e)) 144 | #define debug_mpi(l,t,a) _ntbtls_debug_mpi ((l),(t),(a)) 145 | #define debug_pnt(l,t,a,c) _ntbtls_debug_pnt ((l),(t),(a),(c)) 146 | #define debug_sxp(l,t,a) _ntbtls_debug_sxp ((l),(t),(a)) 147 | #define debug_crt(l,t,a) _ntbtls_debug_crt ((l),(t),(a)) 148 | 149 | 150 | 151 | /* These error codes are used but not defined in the required 152 | libgpg-error version. Define them here. */ 153 | #if GPG_ERROR_VERSION_NUMBER < 0x011b00 /* 1.27 */ 154 | # define GPG_ERR_WRONG_NAME 313 155 | #endif 156 | #if GPG_ERROR_VERSION_NUMBER < 0x011a00 /* 1.26 */ 157 | # define GPG_ERR_UNKNOWN_FLAG 309 158 | # define GPG_ERR_INV_ORDER 310 159 | # define GPG_ERR_ALREADY_FETCHED 311 160 | # define GPG_ERR_TRY_LATER 312 161 | # define GPG_ERR_SYSTEM_BUG 666 162 | # define GPG_ERR_DNS_UNKNOWN 711 163 | # define GPG_ERR_DNS_SECTION 712 164 | # define GPG_ERR_DNS_ADDRESS 713 165 | # define GPG_ERR_DNS_NO_QUERY 714 166 | # define GPG_ERR_DNS_NO_ANSWER 715 167 | # define GPG_ERR_DNS_CLOSED 716 168 | # define GPG_ERR_DNS_VERIFY 717 169 | # define GPG_ERR_DNS_TIMEOUT 718 170 | #endif 171 | 172 | 173 | 174 | 175 | #endif /*NTBTLS_UTIL_H*/ 176 | -------------------------------------------------------------------------------- /src/ntbtls.m4: -------------------------------------------------------------------------------- 1 | dnl Autoconf macros for NTBTLS 2 | dnl Copyright (C) 2002, 2004, 2011 Free Software Foundation, Inc. 3 | dnl 4 | dnl This file is free software; as a special exception the author gives 5 | dnl unlimited permission to copy and/or distribute it, with or without 6 | dnl modifications, as long as this notice is preserved. 7 | dnl 8 | dnl This file is distributed in the hope that it will be useful, but 9 | dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | dnl 12 | dnl Last-changed: 2024-06-13 13 | 14 | 15 | dnl AM_PATH_NTBTLS([MINIMUM-VERSION, 16 | dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) 17 | dnl 18 | dnl Test for NTBTLS and define NTBTLS_CFLAGS and NTBTLS_LIBS. 19 | dnl MINIMUM-VERSION is a string with the version number optionally prefixed 20 | dnl with the API version to also check the API compatibility. Example: 21 | dnl a MINIMUM-VERSION of 1:1.2.5 won't pass the test unless the installed 22 | dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using 23 | dnl this features allows to prevent build against newer versions of libgcrypt 24 | dnl with a changed API. 25 | dnl 26 | AC_DEFUN([AM_PATH_NTBTLS], 27 | [ AC_REQUIRE([AC_CANONICAL_HOST]) 28 | AC_ARG_WITH(ntbtls-prefix, 29 | AS_HELP_STRING([--with-ntbtls-prefix=PFX], 30 | [prefix where NTBTLS is installed (optional)]), 31 | ntbtls_config_prefix="$withval", ntbtls_config_prefix="") 32 | if test x"${NTBTLS_CONFIG}" = x ; then 33 | if test x"${ntbtls_config_prefix}" != x ; then 34 | NTBTLS_CONFIG="${ntbtls_config_prefix}/bin/ntbtls-config" 35 | fi 36 | fi 37 | 38 | use_gpgrt_config="" 39 | if test x"$GPGRT_CONFIG" != x && test "$GPGRT_CONFIG" != "no"; then 40 | if $GPGRT_CONFIG ntbtls --exists; then 41 | NTBTLS_CONFIG="$GPGRT_CONFIG ntbtls" 42 | AC_MSG_NOTICE([Use gpgrt-config as ntbtls-config]) 43 | use_gpgrt_config=yes 44 | fi 45 | fi 46 | if test -z "$use_gpgrt_config"; then 47 | if test x"${NTBTLS_CONFIG}" = x ; then 48 | case "${SYSROOT}" in 49 | /*) 50 | if test -x "${SYSROOT}/bin/ntbtls-config" ; then 51 | NTBTLS_CONFIG="${SYSROOT}/bin/ntbtls-config" 52 | fi 53 | ;; 54 | '') 55 | ;; 56 | *) 57 | AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.]) 58 | ;; 59 | esac 60 | fi 61 | AC_PATH_PROG(NTBTLS_CONFIG, ntbtls-config, no) 62 | fi 63 | 64 | tmp=ifelse([$1], ,1:1.0.0,$1) 65 | if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then 66 | req_ntbtls_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` 67 | min_ntbtls_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` 68 | else 69 | req_ntbtls_api=0 70 | min_ntbtls_version="$tmp" 71 | fi 72 | 73 | AC_MSG_CHECKING(for NTBTLS - version >= $min_ntbtls_version) 74 | ok=no 75 | if test "$NTBTLS_CONFIG" != "no" ; then 76 | req_major=`echo $min_ntbtls_version | \ 77 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` 78 | req_minor=`echo $min_ntbtls_version | \ 79 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` 80 | req_micro=`echo $min_ntbtls_version | \ 81 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` 82 | if test -z "$use_gpgrt_config"; then 83 | ntbtls_config_version=`$NTBTLS_CONFIG --version` 84 | else 85 | ntbtls_config_version=`$NTBTLS_CONFIG --modversion` 86 | fi 87 | major=`echo $ntbtls_config_version | \ 88 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` 89 | minor=`echo $ntbtls_config_version | \ 90 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` 91 | micro=`echo $ntbtls_config_version | \ 92 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` 93 | if test "$major" -gt "$req_major"; then 94 | ok=yes 95 | else 96 | if test "$major" -eq "$req_major"; then 97 | if test "$minor" -gt "$req_minor"; then 98 | ok=yes 99 | else 100 | if test "$minor" -eq "$req_minor"; then 101 | if test "$micro" -ge "$req_micro"; then 102 | ok=yes 103 | fi 104 | fi 105 | fi 106 | fi 107 | fi 108 | fi 109 | if test $ok = yes; then 110 | AC_MSG_RESULT([yes ($ntbtls_config_version)]) 111 | else 112 | AC_MSG_RESULT(no) 113 | fi 114 | if test $ok = yes; then 115 | # If we have a recent ntbtls, we should also check that the 116 | # API is compatible 117 | if test "$req_ntbtls_api" -gt 0 ; then 118 | if test -z "$use_gpgrt_config"; then 119 | tmp=`$NTBTLS_CONFIG --api-version 2>/dev/null || echo 0` 120 | else 121 | tmp=`$NTBTLS_CONFIG --variable=api_version 2>/dev/null || echo 0` 122 | fi 123 | if test "$tmp" -gt 0 ; then 124 | AC_MSG_CHECKING([NTBTLS API version]) 125 | if test "$req_ntbtls_api" -eq "$tmp" ; then 126 | AC_MSG_RESULT([okay]) 127 | else 128 | ok=no 129 | AC_MSG_RESULT([does not match. want=$req_ntbtls_api got=$tmp]) 130 | fi 131 | fi 132 | fi 133 | fi 134 | if test $ok = yes; then 135 | NTBTLS_CFLAGS=`$NTBTLS_CONFIG --cflags` 136 | NTBTLS_LIBS=`$NTBTLS_CONFIG --libs` 137 | ifelse([$2], , :, [$2]) 138 | if test -z "$use_gpgrt_config"; then 139 | ntbtls_config_host=`$NTBTLS_CONFIG --host 2>/dev/null || echo none` 140 | else 141 | ntbtls_config_host=`$NTBTLS_CONFIG --variable=host 2>/dev/null || echo none` 142 | fi 143 | if test x"$ntbtls_config_host" != xnone ; then 144 | if test x"$ntbtls_config_host" != x"$host" ; then 145 | AC_MSG_WARN([[ 146 | *** 147 | *** The config script "$NTBTLS_CONFIG" was 148 | *** built for $ntbtls_config_host and thus may not match the 149 | *** used host $host. 150 | *** You may want to use the configure option --with-ntbtls-prefix 151 | *** to specify a matching config script or use \$SYSROOT. 152 | ***]]) 153 | gpg_config_script_warn="$gpg_config_script_warn ntbtls" 154 | fi 155 | fi 156 | else 157 | NTBTLS_CFLAGS="" 158 | NTBTLS_LIBS="" 159 | ifelse([$3], , :, [$3]) 160 | fi 161 | AC_SUBST(NTBTLS_CFLAGS) 162 | AC_SUBST(NTBTLS_LIBS) 163 | ]) 164 | -------------------------------------------------------------------------------- /src/ntbtls.h.in: -------------------------------------------------------------------------------- 1 | /* ntbtls.h - Not Too Bad TLS -*- c -*- 2 | * Copyright (C) 2014-2022 g10 Code GmbH 3 | * 4 | * This file is part of NTBTLS 5 | * 6 | * NTBTLS is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * NTBTLS is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, see . 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | * 20 | * File: @configure_input@ 21 | */ 22 | 23 | #ifndef _NTBTLS_H 24 | #define _NTBTLS_H 25 | 26 | #include 27 | #include 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #if 0 /* (Keep Emacsens' auto-indent happy.) */ 32 | } 33 | #endif 34 | #endif 35 | 36 | /* 37 | * The version of this header file. 38 | * 39 | * A program should better the fucntion ntbtls_check_version() which 40 | * will return the actual version of the library. The sole purpose of 41 | * this macro is to let autoconf (using the AM_PATH_NTBTLS macro) 42 | * check that this header matches the installed library. 43 | */ 44 | #define NTBTLS_VERSION "@VERSION@" 45 | 46 | /* 47 | * The version number of this header. 48 | * 49 | * It may be used to handle minor API incompatibilities. 50 | */ 51 | #define NTBTLS_VERSION_NUMBER @VERSION_NUMBER@ 52 | 53 | 54 | /* Flags used by ntbtls_new. */ 55 | #define NTBTLS_SERVER 0 56 | #define NTBTLS_CLIENT 1 57 | #define NTBTLS_SAMETRHEAD (1<<4) 58 | 59 | 60 | /* The TLS context object. */ 61 | struct _ntbtls_context_s; 62 | typedef struct _ntbtls_context_s *ntbtls_t; 63 | 64 | 65 | /* 66 | * The type of the verification callback. 67 | * 68 | * This must be registered prior to the handshake and will be called 69 | * by ntbltls when a peer's certificate needs to be verified. OPAQUE 70 | * is the vale set when the callback has been set. TLS is the 71 | * respective TLS context. VERIFY_FLAGS are not yet defined flags. 72 | */ 73 | typedef gpg_error_t (*ntbtls_verify_cb_t) (void *opaque, 74 | ntbtls_t tls, 75 | unsigned int verify_flags); 76 | 77 | 78 | /* 79 | * The type of an optional log handler. 80 | * 81 | * OPAQUE is the value supplied to the set function. LEVEL is the 82 | * debug level for that message; it might be -1 for always log or any 83 | * value less than the limit set with ntbtls_set_debug. FMT is the 84 | * format string. Unless FMT starts with a '\b' the log function is 85 | * expected to append a missing final linefeed. 86 | */ 87 | typedef void (*ntbtls_log_handler_t)(void *opaque, 88 | int level, 89 | const char *fmt, 90 | va_list argv); 91 | 92 | /* Check that the library fulfills the version requirement. */ 93 | const char *ntbtls_check_version (const char *req_version); 94 | 95 | /* Create a new TLS context. */ 96 | gpg_error_t ntbtls_new (ntbtls_t *r_tls, unsigned int flags); 97 | 98 | /* Destroy a TLS context. */ 99 | void ntbtls_release (ntbtls_t tls); 100 | 101 | /* Check that TLS is not NULL and valid. (Use only the macro). */ 102 | gpg_error_t _ntbtls_check_context (ntbtls_t tls, const char *file, int line); 103 | #define ntbtls_check_context(t) _ntbtls_check_context ((t), __FILE__, __LINE__) 104 | 105 | /* Setup the transport streams (usually connected to one socket). */ 106 | gpg_error_t ntbtls_set_transport (ntbtls_t tls, 107 | gpgrt_stream_t inbound, 108 | gpgrt_stream_t outbound); 109 | 110 | /* Get the read and write stream for the plaintext. */ 111 | gpg_error_t ntbtls_get_stream (ntbtls_t tls, 112 | gpgrt_stream_t *r_readfp, 113 | gpgrt_stream_t *r_writefp); 114 | 115 | /* Set the data required to verify peer certificate. */ 116 | gpg_error_t ntbtls_set_verify_cb (ntbtls_t tls, 117 | ntbtls_verify_cb_t cb, void *cb_value); 118 | 119 | /* Set the hostname to check against the received server certificate. 120 | It is used for SNI, too. */ 121 | gpg_error_t ntbtls_set_hostname (ntbtls_t tls, const char *hostname); 122 | 123 | /* Return the hostname which has been set with ntbtls_set_hostname. 124 | * The returned value is valid as long as TLS is valid and 125 | * ntbtls_set_hostname has not been used again. */ 126 | const char *ntbtls_get_hostname (ntbtls_t tls); 127 | 128 | /* Perform the handshake with the peer. The transport streams must be 129 | connected before starting this handshake. */ 130 | gpg_error_t ntbtls_handshake (ntbtls_t tls); 131 | 132 | /* Return the peer's certificate. */ 133 | ksba_cert_t ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx); 134 | 135 | /* Return a string with the last received alert message. NULL is 136 | * return if no alert has yet been received. If R_LEVEL or R_TYPE are 137 | * not NULL the level of the alert and its type are stored tehre. A 138 | * level of 1 is a warning alert and a level of 2 is fatal alert. */ 139 | const char *ntbtls_get_last_alert (ntbtls_t tls, 140 | unsigned int *r_level, unsigned int *r_type); 141 | 142 | /* 143 | * Support functions 144 | */ 145 | 146 | /* Enable debugging at LEVEL (> 0) using an optional PREFIX (default: 147 | * "ntbtls") and an optional debug stream STREAM (default: es_stderr). 148 | * This function is not thread-safe and shall thus be called only once 149 | * before any extra threads have been started. */ 150 | void ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream); 151 | 152 | /* Set a dedicated log handler. See the description of 153 | * ntbtls_log_handler_t for details. This is not thread-safe. */ 154 | void ntbtls_set_log_handler (ntbtls_log_handler_t cb, void *cb_value); 155 | 156 | 157 | #if 0 /* (Keep Emacsens' auto-indent happy.) */ 158 | { 159 | #endif 160 | #ifdef __cplusplus 161 | } 162 | #endif 163 | #endif /* _NTBTLS_H */ 164 | /* 165 | @emacs_local_vars_begin@ 166 | @emacs_local_vars_read_only@ 167 | @emacs_local_vars_end@ 168 | */ 169 | -------------------------------------------------------------------------------- /src/dhm.c: -------------------------------------------------------------------------------- 1 | /* dhm.c - Diffie-Hellman-Merkle key exchange 2 | * Copyright (C) 2014 g10 Code GmbH 3 | * 4 | * This file is part of NTBTLS 5 | * 6 | * NTBTLS is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * NTBTLS is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "ntbtls-int.h" 27 | 28 | 29 | /* While running the validation function we need to keep track of the 30 | certificates and the validation outcome of each. We use this type 31 | for it. */ 32 | struct dhm_context_s 33 | { 34 | gcry_mpi_t dh_p; /* The prime modulus used for the DH operation. */ 35 | gcry_mpi_t dh_g; /* The generator used for the DH operation. */ 36 | gcry_mpi_t dh_Gy; /* The peer's DH public value (g^y mod p). The 37 | value has been checked to fulfill the size 38 | requirements. */ 39 | gcry_mpi_t dh_x; /* Our secret. */ 40 | gcry_mpi_t dh_Gx; /* Our own DH public value (g^x mod p). */ 41 | }; 42 | 43 | 44 | 45 | /* Create a new DHM context. */ 46 | gpg_error_t 47 | _ntbtls_dhm_new (dhm_context_t *r_dhm) 48 | { 49 | dhm_context_t dhm; 50 | 51 | *r_dhm = NULL; 52 | 53 | dhm = calloc (1, sizeof *dhm); 54 | if (!dhm) 55 | return gpg_error_from_syserror (); 56 | 57 | *r_dhm = dhm; 58 | 59 | return 0; 60 | } 61 | 62 | 63 | /* Release a DHM context. */ 64 | void 65 | _ntbtls_dhm_release (dhm_context_t dhm) 66 | { 67 | if (!dhm) 68 | return; 69 | gcry_mpi_release (dhm->dh_p); 70 | gcry_mpi_release (dhm->dh_g); 71 | gcry_mpi_release (dhm->dh_Gy); 72 | gcry_mpi_release (dhm->dh_x); 73 | gcry_mpi_release (dhm->dh_Gx); 74 | free (dhm); 75 | } 76 | 77 | 78 | static gpg_error_t 79 | read_mpi (const unsigned char *data, size_t datalen, 80 | gcry_mpi_t *r_mpi, size_t *r_nscanned) 81 | { 82 | size_t n; 83 | 84 | if (datalen < 2) 85 | return gpg_error (GPG_ERR_TOO_SHORT); 86 | n = ((data[0] << 8) | data[1]); 87 | data += 2; 88 | datalen -= 2; 89 | if (n > datalen) 90 | return gpg_error (GPG_ERR_TOO_LARGE); 91 | *r_nscanned = 2 + n; 92 | return gcry_mpi_scan (r_mpi, GCRYMPI_FMT_USG, data, n, NULL); 93 | } 94 | 95 | 96 | 97 | /* Parse the TLS ServerDHParams and store it in DHM. DER is the 98 | * buffer with the params of length DERLEN. The number of actual 99 | * parsed bytes is stored at R_NPARSED. */ 100 | gpg_error_t 101 | _ntbtls_dhm_read_params (dhm_context_t dhm, const void *_der, size_t derlen, 102 | size_t *r_nparsed) 103 | { 104 | gpg_error_t err; 105 | const unsigned char *der = _der; 106 | size_t n; 107 | gcry_mpi_t a = NULL; 108 | 109 | if (r_nparsed) 110 | *r_nparsed = 0; 111 | 112 | if (!dhm || !der) 113 | return gpg_error (GPG_ERR_INV_ARG); 114 | 115 | gcry_mpi_release (dhm->dh_p); dhm->dh_p = NULL; 116 | gcry_mpi_release (dhm->dh_g); dhm->dh_g = NULL; 117 | gcry_mpi_release (dhm->dh_Gy); dhm->dh_Gy = NULL; 118 | 119 | /* struct { 120 | * opaque dh_p<1..2^16-1>; 121 | * opaque dh_g<1..2^16-1>; 122 | * opaque dh_Ys<1..2^16-1>; 123 | * } ServerDHParams; 124 | */ 125 | err = read_mpi (der, derlen, &dhm->dh_p, &n); 126 | if (err) 127 | goto leave; 128 | debug_mpi (3, "DHM p", dhm->dh_p); 129 | if (r_nparsed) 130 | *r_nparsed += n; 131 | der += n; 132 | derlen -= n; 133 | 134 | err = read_mpi (der, derlen, &dhm->dh_g, &n); 135 | if (err) 136 | goto leave; 137 | debug_mpi (3, "DHM g", dhm->dh_g); 138 | if (r_nparsed) 139 | *r_nparsed += n; 140 | der += n; 141 | derlen -= n; 142 | 143 | err = read_mpi (der, derlen, &dhm->dh_Gy, &n); 144 | if (err) 145 | goto leave; 146 | debug_mpi (3, "DHM Ys", dhm->dh_Gy); 147 | if (r_nparsed) 148 | *r_nparsed += n; 149 | 150 | /* Check for: 2 <= Ys <= P - 2. */ 151 | if (gcry_mpi_cmp_ui (dhm->dh_Gy, 2) < 0) 152 | { 153 | err = gpg_error (GPG_ERR_INV_VALUE); 154 | goto leave; 155 | } 156 | a = gcry_mpi_new (0); 157 | gcry_mpi_sub_ui (a, dhm->dh_p, 2); 158 | if (gcry_mpi_cmp (dhm->dh_Gy, a) > 0) 159 | { 160 | err = gpg_error (GPG_ERR_INV_VALUE); 161 | goto leave; 162 | } 163 | 164 | err = 0; 165 | 166 | leave: 167 | gcry_mpi_release (a); 168 | if (err) 169 | { 170 | gcry_mpi_release (dhm->dh_p); dhm->dh_p = NULL; 171 | gcry_mpi_release (dhm->dh_g); dhm->dh_g = NULL; 172 | gcry_mpi_release (dhm->dh_Gy); dhm->dh_Gy = NULL; 173 | } 174 | 175 | return err; 176 | } 177 | 178 | 179 | /* Return the size of the prime modulus in bits. */ 180 | unsigned int 181 | _ntbtls_dhm_get_nbits (dhm_context_t dhm) 182 | { 183 | if (!dhm || !dhm->dh_p) 184 | return 0; 185 | return gcry_mpi_get_nbits (dhm->dh_p); 186 | } 187 | 188 | 189 | 190 | 191 | /* Create our own private value X and store G^X in OUTBUF. OUTBUFSIZE 192 | is the available length of OUTBUF. On success the actual length of 193 | OUTBUF is stored at R_OUTBUFLEN. */ 194 | gpg_error_t 195 | _ntbtls_dhm_make_public (dhm_context_t dhm, 196 | unsigned char *outbuf, size_t outbufsize, 197 | size_t *r_outbuflen) 198 | { 199 | gpg_error_t err; 200 | unsigned int nbits, nbytes; 201 | size_t n; 202 | gcry_mpi_t dh_pm2; 203 | 204 | if (!dhm || !outbuf || !r_outbuflen) 205 | return gpg_error (GPG_ERR_INV_ARG); 206 | 207 | if (!dhm->dh_p) 208 | return gpg_error (GPG_ERR_NOT_INITIALIZED); 209 | 210 | nbits = gcry_mpi_get_nbits (dhm->dh_p); 211 | if (nbits < 512) 212 | return gpg_error (GPG_ERR_INTERNAL); /* Ooops. */ 213 | nbytes = (nbits +7)/8; 214 | 215 | if (outbufsize < 2 + nbytes) 216 | return gpg_error (GPG_ERR_BUFFER_TOO_SHORT); 217 | 218 | if (!dhm->dh_Gx) 219 | dhm->dh_Gx = gcry_mpi_new (nbits); 220 | 221 | /* Create the random value X and make sure that 2 <= X <= P-2. 222 | Because we truncate X to NBITS-1, it is highly unlikely that this 223 | will ever loop for creating X. Computing Gx is also checked that 224 | it fits into the range and it is also unlikely to loop agains. 225 | Thus we simply allocate a new random value if we ever need to 226 | loop. */ 227 | dh_pm2 = gcry_mpi_new (nbits); 228 | gcry_mpi_sub_ui (dh_pm2, dhm->dh_p, 2); 229 | 230 | if (!dhm->dh_x) 231 | dhm->dh_x = gcry_mpi_snew (nbits); 232 | do 233 | { 234 | do 235 | { 236 | gcry_mpi_randomize (dhm->dh_x, nbits-1, GCRY_STRONG_RANDOM); 237 | gcry_mpi_clear_highbit (dhm->dh_x, nbits); 238 | } 239 | while (gcry_mpi_cmp_ui (dhm->dh_x, 2) < 0 240 | || gcry_mpi_cmp (dhm->dh_x, dh_pm2) > 0); 241 | 242 | gcry_mpi_powm (dhm->dh_Gx, dhm->dh_g, dhm->dh_x, dhm->dh_p); 243 | } 244 | while (gcry_mpi_cmp_ui (dhm->dh_Gx, 2) < 0 245 | || gcry_mpi_cmp (dhm->dh_Gx, dh_pm2) > 0); 246 | 247 | gcry_mpi_release (dh_pm2); 248 | 249 | debug_mpi (4, "DHM x", dhm->dh_x); 250 | debug_mpi (3, "DHM Gx", dhm->dh_Gx); 251 | 252 | outbuf[0] = nbytes >> 8; 253 | outbuf[1] = nbytes; 254 | err = gcry_mpi_print (GCRYMPI_FMT_USG, outbuf+2,outbufsize-2, &n, dhm->dh_Gx); 255 | if (err) 256 | return err; 257 | 258 | *r_outbuflen = 2 + n; 259 | return 0; 260 | } 261 | 262 | 263 | /* Derive the shared secret (G^Y)^X mod P and store it in OUTBUF. 264 | OUTBUFSIZE is the available length of OUTBUF. On success the 265 | actual length of OUTBUF is stored at R_OUTBUFLEN. */ 266 | gpg_error_t 267 | _ntbtls_dhm_calc_secret (dhm_context_t dhm, 268 | unsigned char *outbuf, size_t outbufsize, 269 | size_t *r_outbuflen) 270 | { 271 | gpg_error_t err; 272 | unsigned int nbits, nbytes; 273 | size_t n; 274 | gcry_mpi_t dh_Gyx; 275 | 276 | if (!dhm || !outbuf || !r_outbuflen) 277 | return gpg_error (GPG_ERR_INV_ARG); 278 | 279 | if (!dhm->dh_p || !dhm->dh_x) 280 | return gpg_error (GPG_ERR_NOT_INITIALIZED); 281 | 282 | nbits = gcry_mpi_get_nbits (dhm->dh_p); 283 | if (nbits < 512) 284 | return gpg_error (GPG_ERR_INTERNAL); /* Ooops. */ 285 | nbytes = (nbits +7)/8; 286 | 287 | if (outbufsize < nbytes) 288 | return gpg_error (GPG_ERR_BUFFER_TOO_SHORT); 289 | 290 | //FIXME: Add blinding 291 | dh_Gyx = gcry_mpi_new (nbits); 292 | gcry_mpi_powm (dh_Gyx, dhm->dh_Gy, dhm->dh_x, dhm->dh_p); 293 | 294 | debug_mpi (3, "DHMGyx", dh_Gyx); 295 | 296 | err = gcry_mpi_print (GCRYMPI_FMT_USG, outbuf, outbufsize, &n, dh_Gyx); 297 | gcry_mpi_release (dh_Gyx); 298 | if (err) 299 | return err; 300 | 301 | *r_outbuflen = n; 302 | return 0; 303 | } 304 | -------------------------------------------------------------------------------- /src/pkglue.c: -------------------------------------------------------------------------------- 1 | /* pkglue.c - Public key fucntions 2 | * Copyright (C) 2014 g10 Code GmbH 3 | * 4 | * This file is part of NTBTLS 5 | * 6 | * NTBTLS is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * NTBTLS is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "ntbtls-int.h" 27 | 28 | 29 | static const char * 30 | md_alg_string (md_algo_t md_alg) 31 | { 32 | switch (md_alg) 33 | { 34 | case GCRY_MD_SHA1: return "sha1"; 35 | case GCRY_MD_SHA224: return "sha224"; 36 | case GCRY_MD_SHA256: return "sha256"; 37 | case GCRY_MD_SHA384: return "sha384"; 38 | case GCRY_MD_SHA512: return "sha512"; 39 | case GCRY_MD_RMD160: return "rmd160"; 40 | default: return NULL; 41 | } 42 | } 43 | 44 | 45 | /* Return the public key algorithm id from the S-expression PKEY. 46 | FIXME: libgcrypt should provide such a function. Note that this 47 | implementation uses the names as used by libksba. */ 48 | static pk_algo_t 49 | pk_algo_from_sexp (gcry_sexp_t pkey) 50 | { 51 | gcry_sexp_t l1, l2; 52 | const char *name; 53 | size_t n; 54 | pk_algo_t algo; 55 | 56 | l1 = gcry_sexp_find_token (pkey, "public-key", 0); 57 | if (!l1) 58 | return 0; /* Not found. */ 59 | l2 = gcry_sexp_cadr (l1); 60 | gcry_sexp_release (l1); 61 | 62 | name = gcry_sexp_nth_data (l2, 0, &n); 63 | if (!name) 64 | algo = 0; /* Not found. */ 65 | else if (n==3 && !memcmp (name, "rsa", 3)) 66 | algo = GCRY_PK_RSA; 67 | else if (n==3 && !memcmp (name, "dsa", 3)) 68 | algo = GCRY_PK_DSA; 69 | else if (n==3 && !memcmp (name, "ecc", 3)) 70 | algo = GCRY_PK_ECC; 71 | else if (n==13 && !memcmp (name, "ambiguous-rsa", 13)) 72 | algo = GCRY_PK_RSA; 73 | else 74 | algo = 0; 75 | gcry_sexp_release (l2); 76 | return algo; 77 | } 78 | 79 | 80 | gpg_error_t 81 | _ntbtls_pk_verify (x509_cert_t chain, pk_algo_t pk_alg, md_algo_t md_alg, 82 | const unsigned char *hash, size_t hashlen, 83 | const unsigned char *sig, size_t siglen) 84 | { 85 | gpg_error_t err; 86 | gcry_sexp_t s_pk = NULL; 87 | gcry_sexp_t s_hash = NULL; 88 | gcry_sexp_t s_sig = NULL; 89 | const char *md_alg_str; 90 | 91 | if (!chain ||!md_alg || !hashlen || !sig || !siglen) 92 | return gpg_error (GPG_ERR_INV_ARG); 93 | 94 | md_alg_str = md_alg_string (md_alg); 95 | if (!md_alg_str) 96 | return gpg_error (GPG_ERR_DIGEST_ALGO); 97 | 98 | /* Get the public key from the first certificate. */ 99 | err = _ntbtls_x509_get_pk (chain, 0, &s_pk); 100 | if (err) 101 | goto leave; 102 | 103 | /* Check the Public key algorithm. */ 104 | { 105 | pk_algo_t alg; 106 | 107 | alg = pk_algo_from_sexp (s_pk); 108 | if (!alg) 109 | err = gpg_error (GPG_ERR_PUBKEY_ALGO); 110 | else if (alg != pk_alg) 111 | err = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); /* Does not match. */ 112 | 113 | if (err) 114 | goto leave; 115 | } 116 | 117 | /* Put the hash and the signature into s-expressions. */ 118 | switch (pk_alg) 119 | { 120 | case GCRY_PK_RSA: 121 | err = gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash %s %b))", 122 | md_alg_str, (int)hashlen, hash); 123 | if (!err) 124 | err = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%b)))", 125 | (int)siglen, sig); 126 | break; 127 | 128 | case GCRY_PK_ECC: 129 | { 130 | unsigned int qbits0, qbits; 131 | const unsigned char *r, *s; 132 | int rlen, slen; 133 | 134 | qbits0 = gcry_pk_get_nbits (s_pk); 135 | qbits = qbits0 == 521? 512 : qbits0; 136 | 137 | if ((qbits%8)) 138 | { 139 | debug_msg (1, "qbits are not a multiple of 8 bits"); 140 | err = gpg_error (GPG_ERR_INTERNAL); 141 | goto leave; 142 | } 143 | 144 | if (qbits < 224) 145 | { 146 | debug_msg (1, "key uses an unsafe (%u bit) hash\n", qbits0); 147 | err = gpg_error (GPG_ERR_UNUSABLE_PUBKEY); 148 | goto leave; 149 | } 150 | 151 | /* 152 | * For TLS 1.2, it is possible for a server to use SHA256 with 153 | * secpr384 key. See RFC8422 section 5.10. 154 | */ 155 | if (0 && hashlen < qbits/8) 156 | { 157 | debug_msg (1, "a %u bit hash is not valid for a %u bit ECC key", 158 | (unsigned int)hashlen*8, qbits); 159 | err = gpg_error (GPG_ERR_DIGEST_ALGO); 160 | goto leave; 161 | } 162 | 163 | if (hashlen > qbits/8) 164 | hashlen = qbits/8; /* Truncate. */ 165 | 166 | err = gcry_sexp_build (&s_hash, NULL, "(data (flags raw)(value %b))", 167 | (int)hashlen, hash); 168 | if (err) 169 | goto leave; 170 | /* 3045 -- SEQUENCE with length 0x45 171 | * 0220 -- INTEGER with length 0x20 172 | * 3045bcceccda9464c1d340a225e55e3d045e17ce004c0508a2cd61dd 173 | * 23a63ba6 174 | * 0221 -- INTEGER with length 0x21 (due to 0x00 prefix) 175 | * 00e39b404793be76e87089ff3b5c306246a9f8cb52d94c77c624c3bf 176 | * 118e2418e8 177 | */ 178 | if (siglen < 6 || sig[0] != 0x30 || sig[1] != siglen - 2 179 | || sig[2] != 0x02) 180 | { 181 | err = gpg_error (GPG_ERR_INV_BER); 182 | goto leave; 183 | } 184 | siglen -= 2; 185 | sig += 2; 186 | rlen = sig[1]; 187 | if ((rlen != 32 && rlen != 33 188 | && rlen != 48 && rlen != 49 189 | && rlen != 64 && rlen != 65) 190 | || (rlen + 2 > siglen)) 191 | { 192 | /* The signature length is not 256, 384 or 512 bit. The 193 | * odd values are to handle an extra zero prefix. Or 194 | * the length is larger than the entire frame. */ 195 | err = gpg_error (GPG_ERR_INV_LENGTH); 196 | goto leave; 197 | } 198 | r = sig + 2; 199 | sig = r + rlen; 200 | siglen -= rlen + 2; 201 | if (siglen < 3 || sig[0] != 0x02) 202 | { 203 | err = gpg_error (GPG_ERR_INV_BER); 204 | goto leave; 205 | } 206 | siglen -= 2; 207 | slen = sig[1]; 208 | if ((slen > siglen) || ((rlen & ~1) != (slen & ~1))) 209 | { 210 | /* The length of S does not match the length of R. Or 211 | * the length is larger than the entire frame. */ 212 | err = gpg_error (GPG_ERR_INV_LENGTH); 213 | goto leave; 214 | } 215 | s = sig + 2; 216 | err = gcry_sexp_build (&s_sig, NULL, "(sig-val(ecdsa(r%b)(s%b)))", 217 | rlen, r, slen, s); 218 | } 219 | break; 220 | 221 | default: 222 | err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); 223 | break; 224 | } 225 | if (err) 226 | goto leave; 227 | 228 | debug_sxp (4, "sig ", s_sig); 229 | debug_sxp (4, "hash", s_hash); 230 | debug_sxp (4, "pk ", s_pk); 231 | err = gcry_pk_verify (s_sig, s_hash, s_pk); 232 | debug_msg (4, "res=%d", err); 233 | 234 | leave: 235 | gcry_sexp_release (s_pk); 236 | gcry_sexp_release (s_hash); 237 | gcry_sexp_release (s_sig); 238 | return err; 239 | } 240 | 241 | 242 | gpg_error_t 243 | _ntbtls_pk_encrypt (x509_cert_t chain, 244 | const unsigned char *input, size_t ilen, 245 | unsigned char *output, size_t *olen, size_t osize) 246 | { 247 | gpg_error_t err; 248 | gcry_sexp_t s_pk = NULL; 249 | gcry_sexp_t s_data = NULL; 250 | gcry_sexp_t s_ciph = NULL; 251 | size_t len; 252 | const char *data; 253 | 254 | /* Get the public key from the first certificate. */ 255 | err = _ntbtls_x509_get_pk (chain, 0, &s_pk); 256 | if (err) 257 | return err; 258 | 259 | err = gcry_sexp_build (&s_data, NULL, "(data (flags pkcs1) (value %b))", 260 | (int)ilen, input); 261 | if (err) 262 | { 263 | gcry_sexp_release (s_pk); 264 | return err; 265 | } 266 | 267 | err = gcry_pk_encrypt (&s_ciph, s_data, s_pk); 268 | gcry_sexp_release (s_data); 269 | s_data = NULL; 270 | gcry_sexp_release (s_pk); 271 | s_pk = NULL; 272 | if (err) 273 | return err; 274 | 275 | s_data = gcry_sexp_find_token (s_ciph, "a", 0); 276 | data = gcry_sexp_nth_data (s_data, 1, &len); 277 | if (data == NULL) 278 | err = gpg_error (GPG_ERR_BAD_MPI); 279 | else if (osize < len) 280 | err = gpg_error (GPG_ERR_TOO_SHORT); 281 | else 282 | { 283 | *olen = len; 284 | memcpy (output, data, len); 285 | } 286 | 287 | gcry_sexp_release (s_data); 288 | gcry_sexp_release (s_ciph); 289 | return err; 290 | } 291 | -------------------------------------------------------------------------------- /m4/ksba.m4: -------------------------------------------------------------------------------- 1 | # ksba.m4 - autoconf macro to detect ksba 2 | # Copyright (C) 2002, 2018, 2024 g10 Code GmbH 3 | # 4 | # This file is free software; as a special exception the author gives 5 | # unlimited permission to copy and/or distribute it, with or without 6 | # modifications, as long as this notice is preserved. 7 | # 8 | # This file is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | # 12 | # Last-changed: 2024-06-13 13 | 14 | dnl 15 | dnl Find gpgrt-config, which uses .pc file 16 | dnl (minimum pkg-config functionality, supporting cross build) 17 | dnl 18 | dnl _AM_PATH_GPGRT_CONFIG 19 | AC_DEFUN([_AM_PATH_GPGRT_CONFIG],[dnl 20 | AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no, [$prefix/bin:$PATH]) 21 | if test "$GPGRT_CONFIG" != "no"; then 22 | # Determine gpgrt_libdir 23 | # 24 | # Get the prefix of gpgrt-config assuming it's something like: 25 | # /bin/gpgrt-config 26 | gpgrt_prefix=${GPGRT_CONFIG%/*/*} 27 | possible_libdir1=${gpgrt_prefix}/lib 28 | # Determine by using system libdir-format with CC, it's like: 29 | # Normal style: /usr/lib 30 | # GNU cross style: /usr//lib 31 | # Debian style: /usr/lib/ 32 | # Fedora/openSUSE style: /usr/lib, /usr/lib32 or /usr/lib64 33 | # It is assumed that CC is specified to the one of host on cross build. 34 | if libdir_candidates=$(${CC:-cc} -print-search-dirs | \ 35 | sed -n -e "/^libraries/{s/libraries: =//;s/:/\\ 36 | /g;p;}"); then 37 | # From the output of -print-search-dirs, select valid pkgconfig dirs. 38 | libdir_candidates=$(for dir in $libdir_candidates; do 39 | if p=$(cd $dir 2>/dev/null && pwd); then 40 | test -d "$p/pkgconfig" && echo $p; 41 | fi 42 | done) 43 | 44 | for possible_libdir0 in $libdir_candidates; do 45 | # possible_libdir0: 46 | # Fallback candidate, the one of system-installed (by $CC) 47 | # (/usr//lib, /usr/lib/ or /usr/lib32) 48 | # possible_libdir1: 49 | # Another candidate, user-locally-installed 50 | # (/lib) 51 | # possible_libdir2 52 | # Most preferred 53 | # (//lib, 54 | # /lib/ or /lib32) 55 | if test "${possible_libdir0##*/}" = "lib"; then 56 | possible_prefix0=${possible_libdir0%/lib} 57 | possible_prefix0_triplet=${possible_prefix0##*/} 58 | if test -z "$possible_prefix0_triplet"; then 59 | continue 60 | fi 61 | possible_libdir2=${gpgrt_prefix}/$possible_prefix0_triplet/lib 62 | else 63 | possible_prefix0=${possible_libdir0%%/lib*} 64 | possible_libdir2=${gpgrt_prefix}${possible_libdir0#$possible_prefix0} 65 | fi 66 | if test -f ${possible_libdir2}/pkgconfig/gpg-error.pc; then 67 | gpgrt_libdir=${possible_libdir2} 68 | elif test -f ${possible_libdir1}/pkgconfig/gpg-error.pc; then 69 | gpgrt_libdir=${possible_libdir1} 70 | elif test -f ${possible_libdir0}/pkgconfig/gpg-error.pc; then 71 | gpgrt_libdir=${possible_libdir0} 72 | fi 73 | if test -n "$gpgrt_libdir"; then break; fi 74 | done 75 | fi 76 | if test -z "$gpgrt_libdir"; then 77 | # No valid pkgconfig dir in any of the system directories, fallback 78 | gpgrt_libdir=${possible_libdir1} 79 | fi 80 | else 81 | unset GPGRT_CONFIG 82 | fi 83 | 84 | if test -n "$gpgrt_libdir"; then 85 | # Add the --libdir option to GPGRT_CONFIG 86 | GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir" 87 | # Make sure if gpgrt-config really works, by testing config gpg-error 88 | if ! $GPGRT_CONFIG gpg-error --exists; then 89 | # If it doesn't work, clear the GPGRT_CONFIG variable. 90 | unset GPGRT_CONFIG 91 | fi 92 | else 93 | # GPGRT_CONFIG found but no suitable dir for --libdir found. 94 | # This is a failure. Clear the GPGRT_CONFIG variable. 95 | unset GPGRT_CONFIG 96 | fi 97 | ]) 98 | 99 | dnl AM_PATH_KSBA([MINIMUM-VERSION, 100 | dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) 101 | dnl Test for libksba and define KSBA_CFLAGS and KSBA_LIBS 102 | dnl MINIMUM-VERSION is a string with the version number optionally prefixed 103 | dnl with the API version to also check the API compatibility. Example: 104 | dnl a MINIMUM-VERSION of 1:1.0.7 won't pass the test unless the installed 105 | dnl version of libksba is at least 1.0.7 *and* the API number is 1. Using 106 | dnl this features allows to prevent build against newer versions of libksba 107 | dnl with a changed API. 108 | dnl 109 | AC_DEFUN([AM_PATH_KSBA], 110 | [ AC_REQUIRE([AC_CANONICAL_HOST])dnl 111 | AC_REQUIRE([_AM_PATH_GPGRT_CONFIG])dnl 112 | dnl --with-libksba-prefix=PFX is the preferred name for this option, 113 | dnl since that is consistent with how our three siblings use the directory/ 114 | dnl package name in --with-$dir_name-prefix=PFX. 115 | AC_ARG_WITH(libksba-prefix, 116 | AS_HELP_STRING([--with-libksba-prefix=PFX], 117 | [prefix where KSBA is installed (optional)]), 118 | ksba_config_prefix="$withval", ksba_config_prefix="") 119 | 120 | dnl Accept --with-ksba-prefix and make it work the same as 121 | dnl --with-libksba-prefix above, for backwards compatibility, 122 | dnl but do not document this old, inconsistently-named option. 123 | AC_ARG_WITH(ksba-prefix,, 124 | ksba_config_prefix="$withval", ksba_config_prefix="") 125 | 126 | if test x$ksba_config_prefix != x ; then 127 | if test x${KSBA_CONFIG+set} != xset ; then 128 | KSBA_CONFIG=$ksba_config_prefix/bin/ksba-config 129 | fi 130 | fi 131 | 132 | use_gpgrt_config="" 133 | if test x"$GPGRT_CONFIG" != x -a "$GPGRT_CONFIG" != "no"; then 134 | if $GPGRT_CONFIG ksba --exists; then 135 | KSBA_CONFIG="$GPGRT_CONFIG ksba" 136 | AC_MSG_NOTICE([Use gpgrt-config as ksba-config]) 137 | use_gpgrt_config=yes 138 | fi 139 | fi 140 | if test -z "$use_gpgrt_config"; then 141 | AC_PATH_PROG(KSBA_CONFIG, ksba-config, no) 142 | fi 143 | 144 | tmp=ifelse([$1], ,1:1.0.0,$1) 145 | if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then 146 | req_ksba_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` 147 | min_ksba_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` 148 | else 149 | req_ksba_api=0 150 | min_ksba_version="$tmp" 151 | fi 152 | 153 | AC_MSG_CHECKING(for KSBA - version >= $min_ksba_version) 154 | ok=no 155 | if test "$KSBA_CONFIG" != "no" ; then 156 | req_major=`echo $min_ksba_version | \ 157 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` 158 | req_minor=`echo $min_ksba_version | \ 159 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` 160 | req_micro=`echo $min_ksba_version | \ 161 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` 162 | if test -z "$use_gpgrt_config"; then 163 | ksba_config_version=`$KSBA_CONFIG --version` 164 | else 165 | ksba_config_version=`$KSBA_CONFIG --modversion` 166 | fi 167 | major=`echo $ksba_config_version | \ 168 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` 169 | minor=`echo $ksba_config_version | \ 170 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` 171 | micro=`echo $ksba_config_version | \ 172 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` 173 | if test "$major" -gt "$req_major"; then 174 | ok=yes 175 | else 176 | if test "$major" -eq "$req_major"; then 177 | if test "$minor" -gt "$req_minor"; then 178 | ok=yes 179 | else 180 | if test "$minor" -eq "$req_minor"; then 181 | if test "$micro" -ge "$req_micro"; then 182 | ok=yes 183 | fi 184 | fi 185 | fi 186 | fi 187 | fi 188 | fi 189 | if test $ok = yes; then 190 | AC_MSG_RESULT([yes ($ksba_config_version)]) 191 | else 192 | AC_MSG_RESULT(no) 193 | fi 194 | if test $ok = yes; then 195 | # Even if we have a recent libksba, we should check that the 196 | # API is compatible. 197 | if test "$req_ksba_api" -gt 0 ; then 198 | if test -z "$use_gpgrt_config"; then 199 | tmp=`$KSBA_CONFIG --api-version 2>/dev/null || echo 0` 200 | else 201 | tmp=`$KSBA_CONFIG --variable=api_version 2>/dev/null || echo 0` 202 | fi 203 | if test "$tmp" -gt 0 ; then 204 | AC_MSG_CHECKING([KSBA API version]) 205 | if test "$req_ksba_api" -eq "$tmp" ; then 206 | AC_MSG_RESULT(okay) 207 | else 208 | ok=no 209 | AC_MSG_RESULT([does not match. want=$req_ksba_api got=$tmp.]) 210 | fi 211 | fi 212 | fi 213 | fi 214 | if test $ok = yes; then 215 | KSBA_CFLAGS=`$KSBA_CONFIG --cflags` 216 | KSBA_LIBS=`$KSBA_CONFIG --libs` 217 | ifelse([$2], , :, [$2]) 218 | if test -z "$use_gpgrt_config"; then 219 | libksba_config_host=`$KSBA_CONFIG --host 2>/dev/null || echo none` 220 | else 221 | libksba_config_host=`$KSBA_CONFIG --variable=host 2>/dev/null || echo none` 222 | fi 223 | if test x"$libksba_config_host" != xnone ; then 224 | if test x"$libksba_config_host" != x"$host" ; then 225 | AC_MSG_WARN([[ 226 | *** 227 | *** The config script "$KSBA_CONFIG" was 228 | *** built for $libksba_config_host and thus may not match the 229 | *** used host $host. 230 | *** You may want to use the configure option --with-libksba-prefix 231 | *** to specify a matching config script. 232 | ***]]) 233 | fi 234 | fi 235 | else 236 | KSBA_CFLAGS="" 237 | KSBA_LIBS="" 238 | ifelse([$3], , :, [$3]) 239 | fi 240 | AC_SUBST(KSBA_CFLAGS) 241 | AC_SUBST(KSBA_LIBS) 242 | ]) 243 | -------------------------------------------------------------------------------- /m4/gpg-error.m4: -------------------------------------------------------------------------------- 1 | # gpg-error.m4 - autoconf macro to detect libgpg-error. 2 | # Copyright (C) 2002, 2003, 2004, 2011, 2014, 2018, 2020, 2021, 2022, 2024 3 | # g10 Code GmbH 4 | # 5 | # This file is free software; as a special exception the author gives 6 | # unlimited permission to copy and/or distribute it, with or without 7 | # modifications, as long as this notice is preserved. 8 | # 9 | # This file is distributed in the hope that it will be useful, but 10 | # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 11 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | # 13 | # Last-changed: 2024-06-13 14 | 15 | dnl 16 | dnl Find gpg-error-config, for backward compatibility 17 | dnl 18 | dnl _AM_PATH_POSSIBLE_GPG_ERROR_CONFIG 19 | AC_DEFUN([_AM_PATH_POSSIBLE_GPG_ERROR_CONFIG],[dnl 20 | gpg_error_config_prefix="" 21 | dnl --with-libgpg-error-prefix=PFX is the preferred name for this option, 22 | dnl since that is consistent with how our three siblings use the directory/ 23 | dnl package name in --with-$dir_name-prefix=PFX. 24 | AC_ARG_WITH(libgpg-error-prefix, 25 | AS_HELP_STRING([--with-libgpg-error-prefix=PFX], 26 | [prefix where GPG Error is installed (optional)]), 27 | [gpg_error_config_prefix="$withval"]) 28 | 29 | dnl Accept --with-gpg-error-prefix and make it work the same as 30 | dnl --with-libgpg-error-prefix above, for backwards compatibility, 31 | dnl but do not document this old, inconsistently-named option. 32 | AC_ARG_WITH(gpg-error-prefix,, 33 | [gpg_error_config_prefix="$withval"]) 34 | 35 | if test x"${GPG_ERROR_CONFIG}" = x ; then 36 | if test x"${gpg_error_config_prefix}" != x ; then 37 | GPG_ERROR_CONFIG="${gpg_error_config_prefix}/bin/gpg-error-config" 38 | else 39 | case "${SYSROOT}" in 40 | /*) 41 | if test -x "${SYSROOT}/bin/gpg-error-config" ; then 42 | GPG_ERROR_CONFIG="${SYSROOT}/bin/gpg-error-config" 43 | fi 44 | ;; 45 | '') 46 | ;; 47 | *) 48 | AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.]) 49 | ;; 50 | esac 51 | fi 52 | fi 53 | 54 | AC_PATH_PROG(GPG_ERROR_CONFIG, gpg-error-config, no) 55 | ]) 56 | 57 | dnl 58 | dnl Find gpgrt-config, which uses .pc file 59 | dnl (minimum pkg-config functionality, supporting cross build) 60 | dnl 61 | dnl _AM_PATH_GPGRT_CONFIG 62 | AC_DEFUN([_AM_PATH_GPGRT_CONFIG],[dnl 63 | AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no, [$prefix/bin:$PATH]) 64 | if test "$GPGRT_CONFIG" != "no"; then 65 | # Determine gpgrt_libdir 66 | # 67 | # Get the prefix of gpgrt-config assuming it's something like: 68 | # /bin/gpgrt-config 69 | gpgrt_prefix=${GPGRT_CONFIG%/*/*} 70 | possible_libdir1=${gpgrt_prefix}/lib 71 | # Determine by using system libdir-format with CC, it's like: 72 | # Normal style: /usr/lib 73 | # GNU cross style: /usr//lib 74 | # Debian style: /usr/lib/ 75 | # Fedora/openSUSE style: /usr/lib, /usr/lib32 or /usr/lib64 76 | # It is assumed that CC is specified to the one of host on cross build. 77 | if libdir_candidates=$(${CC:-cc} -print-search-dirs | \ 78 | sed -n -e "/^libraries/{s/libraries: =//;s/:/\\ 79 | /g;p;}"); then 80 | # From the output of -print-search-dirs, select valid pkgconfig dirs. 81 | libdir_candidates=$(for dir in $libdir_candidates; do 82 | if p=$(cd $dir 2>/dev/null && pwd); then 83 | test -d "$p/pkgconfig" && echo $p; 84 | fi 85 | done) 86 | 87 | for possible_libdir0 in $libdir_candidates; do 88 | # possible_libdir0: 89 | # Fallback candidate, the one of system-installed (by $CC) 90 | # (/usr//lib, /usr/lib/ or /usr/lib32) 91 | # possible_libdir1: 92 | # Another candidate, user-locally-installed 93 | # (/lib) 94 | # possible_libdir2 95 | # Most preferred 96 | # (//lib, 97 | # /lib/ or /lib32) 98 | if test "${possible_libdir0##*/}" = "lib"; then 99 | possible_prefix0=${possible_libdir0%/lib} 100 | possible_prefix0_triplet=${possible_prefix0##*/} 101 | if test -z "$possible_prefix0_triplet"; then 102 | continue 103 | fi 104 | possible_libdir2=${gpgrt_prefix}/$possible_prefix0_triplet/lib 105 | else 106 | possible_prefix0=${possible_libdir0%%/lib*} 107 | possible_libdir2=${gpgrt_prefix}${possible_libdir0#$possible_prefix0} 108 | fi 109 | if test -f ${possible_libdir2}/pkgconfig/gpg-error.pc; then 110 | gpgrt_libdir=${possible_libdir2} 111 | elif test -f ${possible_libdir1}/pkgconfig/gpg-error.pc; then 112 | gpgrt_libdir=${possible_libdir1} 113 | elif test -f ${possible_libdir0}/pkgconfig/gpg-error.pc; then 114 | gpgrt_libdir=${possible_libdir0} 115 | fi 116 | if test -n "$gpgrt_libdir"; then break; fi 117 | done 118 | fi 119 | if test -z "$gpgrt_libdir"; then 120 | # No valid pkgconfig dir in any of the system directories, fallback 121 | gpgrt_libdir=${possible_libdir1} 122 | fi 123 | else 124 | unset GPGRT_CONFIG 125 | fi 126 | 127 | if test -n "$gpgrt_libdir"; then 128 | # Add the --libdir option to GPGRT_CONFIG 129 | GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir" 130 | # Make sure if gpgrt-config really works, by testing config gpg-error 131 | if ! $GPGRT_CONFIG gpg-error --exists; then 132 | # If it doesn't work, clear the GPGRT_CONFIG variable. 133 | unset GPGRT_CONFIG 134 | fi 135 | else 136 | # GPGRT_CONFIG found but no suitable dir for --libdir found. 137 | # This is a failure. Clear the GPGRT_CONFIG variable. 138 | unset GPGRT_CONFIG 139 | fi 140 | ]) 141 | 142 | dnl AM_PATH_GPG_ERROR([MINIMUM-VERSION, 143 | dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) 144 | dnl 145 | dnl Test for libgpg-error and define GPG_ERROR_CFLAGS, GPG_ERROR_LIBS, 146 | dnl GPG_ERROR_MT_CFLAGS, and GPG_ERROR_MT_LIBS. The _MT_ variants are 147 | dnl used for programs requiring real multi thread support. 148 | dnl 149 | dnl If a prefix option is not used, the config script is first 150 | dnl searched in $SYSROOT/bin and then along $PATH. If the used 151 | dnl config script does not match the host specification the script 152 | dnl is added to the gpg_config_script_warn variable. 153 | dnl 154 | AC_DEFUN([AM_PATH_GPG_ERROR], 155 | [ AC_REQUIRE([AC_CANONICAL_HOST])dnl 156 | AC_REQUIRE([_AM_PATH_POSSIBLE_GPG_ERROR_CONFIG])dnl 157 | AC_REQUIRE([_AM_PATH_GPGRT_CONFIG])dnl 158 | if test x"$GPGRT_CONFIG" != x -a "$GPGRT_CONFIG" != "no"; then 159 | GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error" 160 | AC_MSG_NOTICE([Use gpgrt-config with $gpgrt_libdir as gpg-error-config]) 161 | gpg_error_config_version=`$GPG_ERROR_CONFIG --modversion` 162 | elif test x"$GPG_ERROR_CONFIG" != x -a "$GPG_ERROR_CONFIG" != "no"; then 163 | gpg_error_config_version=`$GPG_ERROR_CONFIG --version` 164 | else 165 | gpg_error_config_version="0.0" 166 | fi 167 | 168 | min_gpg_error_version=ifelse([$1], ,1.33,$1) 169 | ok=no 170 | if test "$GPG_ERROR_CONFIG" != "no"; then 171 | req_major=`echo $min_gpg_error_version | \ 172 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` 173 | req_minor=`echo $min_gpg_error_version | \ 174 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` 175 | major=`echo $gpg_error_config_version | \ 176 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` 177 | minor=`echo $gpg_error_config_version | \ 178 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` 179 | if test "$major" -gt "$req_major"; then 180 | ok=yes 181 | else 182 | if test "$major" -eq "$req_major"; then 183 | if test "$minor" -ge "$req_minor"; then 184 | ok=yes 185 | fi 186 | fi 187 | fi 188 | fi 189 | AC_MSG_CHECKING(for GPG Error - version >= $min_gpg_error_version) 190 | if test $ok = yes; then 191 | GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG --cflags` 192 | GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG --libs` 193 | if test -z "$GPGRT_CONFIG"; then 194 | GPG_ERROR_MT_CFLAGS=`$GPG_ERROR_CONFIG --mt --cflags 2>/dev/null` 195 | GPG_ERROR_MT_LIBS=`$GPG_ERROR_CONFIG --mt --libs 2>/dev/null` 196 | else 197 | GPG_ERROR_MT_CFLAGS=`$GPG_ERROR_CONFIG --variable=mtcflags 2>/dev/null` 198 | GPG_ERROR_MT_CFLAGS="$GPG_ERROR_CFLAGS${GPG_ERROR_CFLAGS:+ }$GPG_ERROR_MT_CFLAGS" 199 | GPG_ERROR_MT_LIBS=`$GPG_ERROR_CONFIG --variable=mtlibs 2>/dev/null` 200 | GPG_ERROR_MT_LIBS="$GPG_ERROR_LIBS${GPG_ERROR_LIBS:+ }$GPG_ERROR_MT_LIBS" 201 | fi 202 | AC_MSG_RESULT([yes ($gpg_error_config_version)]) 203 | ifelse([$2], , :, [$2]) 204 | if test -z "$GPGRT_CONFIG"; then 205 | gpg_error_config_host=`$GPG_ERROR_CONFIG --host 2>/dev/null || echo none` 206 | else 207 | gpg_error_config_host=`$GPG_ERROR_CONFIG --variable=host 2>/dev/null || echo none` 208 | fi 209 | if test x"$gpg_error_config_host" != xnone ; then 210 | if test x"$gpg_error_config_host" != x"$host" ; then 211 | AC_MSG_WARN([[ 212 | *** 213 | *** The config script "$GPG_ERROR_CONFIG" was 214 | *** built for $gpg_error_config_host and thus may not match the 215 | *** used host $host. 216 | *** You may want to use the configure option --with-libgpg-error-prefix 217 | *** to specify a matching config script or use \$SYSROOT. 218 | ***]]) 219 | gpg_config_script_warn="$gpg_config_script_warn libgpg-error" 220 | fi 221 | fi 222 | else 223 | GPG_ERROR_CFLAGS="" 224 | GPG_ERROR_LIBS="" 225 | GPG_ERROR_MT_CFLAGS="" 226 | GPG_ERROR_MT_LIBS="" 227 | AC_MSG_RESULT(no) 228 | ifelse([$3], , :, [$3]) 229 | fi 230 | AC_SUBST(GPG_ERROR_CFLAGS) 231 | AC_SUBST(GPG_ERROR_LIBS) 232 | AC_SUBST(GPG_ERROR_MT_CFLAGS) 233 | AC_SUBST(GPG_ERROR_MT_LIBS) 234 | ]) 235 | -------------------------------------------------------------------------------- /m4/libgcrypt.m4: -------------------------------------------------------------------------------- 1 | # libgcrypt.m4 - Autoconf macros to detect libgcrypt 2 | # Copyright (C) 2002, 2003, 2004, 2011, 2014, 2018, 2020, 3 | # 2024 g10 Code GmbH 4 | # 5 | # This file is free software; as a special exception the author gives 6 | # unlimited permission to copy and/or distribute it, with or without 7 | # modifications, as long as this notice is preserved. 8 | # 9 | # This file is distributed in the hope that it will be useful, but 10 | # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 11 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | # 13 | # Last-changed: 2024-06-13 14 | 15 | 16 | dnl 17 | dnl Find gpgrt-config, which uses .pc file 18 | dnl (minimum pkg-config functionality, supporting cross build) 19 | dnl 20 | dnl _AM_PATH_GPGRT_CONFIG 21 | AC_DEFUN([_AM_PATH_GPGRT_CONFIG],[dnl 22 | AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no, [$prefix/bin:$PATH]) 23 | if test "$GPGRT_CONFIG" != "no"; then 24 | # Determine gpgrt_libdir 25 | # 26 | # Get the prefix of gpgrt-config assuming it's something like: 27 | # /bin/gpgrt-config 28 | gpgrt_prefix=${GPGRT_CONFIG%/*/*} 29 | possible_libdir1=${gpgrt_prefix}/lib 30 | # Determine by using system libdir-format with CC, it's like: 31 | # Normal style: /usr/lib 32 | # GNU cross style: /usr//lib 33 | # Debian style: /usr/lib/ 34 | # Fedora/openSUSE style: /usr/lib, /usr/lib32 or /usr/lib64 35 | # It is assumed that CC is specified to the one of host on cross build. 36 | if libdir_candidates=$(${CC:-cc} -print-search-dirs | \ 37 | sed -n -e "/^libraries/{s/libraries: =//;s/:/\\ 38 | /g;p;}"); then 39 | # From the output of -print-search-dirs, select valid pkgconfig dirs. 40 | libdir_candidates=$(for dir in $libdir_candidates; do 41 | if p=$(cd $dir 2>/dev/null && pwd); then 42 | test -d "$p/pkgconfig" && echo $p; 43 | fi 44 | done) 45 | 46 | for possible_libdir0 in $libdir_candidates; do 47 | # possible_libdir0: 48 | # Fallback candidate, the one of system-installed (by $CC) 49 | # (/usr//lib, /usr/lib/ or /usr/lib32) 50 | # possible_libdir1: 51 | # Another candidate, user-locally-installed 52 | # (/lib) 53 | # possible_libdir2 54 | # Most preferred 55 | # (//lib, 56 | # /lib/ or /lib32) 57 | if test "${possible_libdir0##*/}" = "lib"; then 58 | possible_prefix0=${possible_libdir0%/lib} 59 | possible_prefix0_triplet=${possible_prefix0##*/} 60 | if test -z "$possible_prefix0_triplet"; then 61 | continue 62 | fi 63 | possible_libdir2=${gpgrt_prefix}/$possible_prefix0_triplet/lib 64 | else 65 | possible_prefix0=${possible_libdir0%%/lib*} 66 | possible_libdir2=${gpgrt_prefix}${possible_libdir0#$possible_prefix0} 67 | fi 68 | if test -f ${possible_libdir2}/pkgconfig/gpg-error.pc; then 69 | gpgrt_libdir=${possible_libdir2} 70 | elif test -f ${possible_libdir1}/pkgconfig/gpg-error.pc; then 71 | gpgrt_libdir=${possible_libdir1} 72 | elif test -f ${possible_libdir0}/pkgconfig/gpg-error.pc; then 73 | gpgrt_libdir=${possible_libdir0} 74 | fi 75 | if test -n "$gpgrt_libdir"; then break; fi 76 | done 77 | fi 78 | if test -z "$gpgrt_libdir"; then 79 | # No valid pkgconfig dir in any of the system directories, fallback 80 | gpgrt_libdir=${possible_libdir1} 81 | fi 82 | else 83 | unset GPGRT_CONFIG 84 | fi 85 | 86 | if test -n "$gpgrt_libdir"; then 87 | # Add the --libdir option to GPGRT_CONFIG 88 | GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir" 89 | # Make sure if gpgrt-config really works, by testing config gpg-error 90 | if ! $GPGRT_CONFIG gpg-error --exists; then 91 | # If it doesn't work, clear the GPGRT_CONFIG variable. 92 | unset GPGRT_CONFIG 93 | fi 94 | else 95 | # GPGRT_CONFIG found but no suitable dir for --libdir found. 96 | # This is a failure. Clear the GPGRT_CONFIG variable. 97 | unset GPGRT_CONFIG 98 | fi 99 | ]) 100 | 101 | dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, 102 | dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) 103 | dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS. 104 | dnl MINIMUM-VERSION is a string with the version number optionally prefixed 105 | dnl with the API version to also check the API compatibility. Example: 106 | dnl a MINIMUM-VERSION of 1:1.2.5 won't pass the test unless the installed 107 | dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using 108 | dnl this features allows to prevent build against newer versions of libgcrypt 109 | dnl with a changed API. 110 | dnl 111 | dnl If a prefix option is not used, the config script is first 112 | dnl searched in $SYSROOT/bin and then along $PATH. If the used 113 | dnl config script does not match the host specification the script 114 | dnl is added to the gpg_config_script_warn variable. 115 | dnl 116 | AC_DEFUN([AM_PATH_LIBGCRYPT], 117 | [ AC_REQUIRE([AC_CANONICAL_HOST])dnl 118 | AC_REQUIRE([_AM_PATH_GPGRT_CONFIG])dnl 119 | AC_ARG_WITH(libgcrypt-prefix, 120 | AS_HELP_STRING([--with-libgcrypt-prefix=PFX], 121 | [prefix where LIBGCRYPT is installed (optional)]), 122 | libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="") 123 | if test x"${LIBGCRYPT_CONFIG}" = x ; then 124 | if test x"${libgcrypt_config_prefix}" != x ; then 125 | LIBGCRYPT_CONFIG="${libgcrypt_config_prefix}/bin/libgcrypt-config" 126 | fi 127 | fi 128 | 129 | use_gpgrt_config="" 130 | if test x"$GPGRT_CONFIG" != x -a "$GPGRT_CONFIG" != "no"; then 131 | if $GPGRT_CONFIG libgcrypt --exists; then 132 | LIBGCRYPT_CONFIG="$GPGRT_CONFIG libgcrypt" 133 | AC_MSG_NOTICE([Use gpgrt-config as libgcrypt-config]) 134 | use_gpgrt_config=yes 135 | fi 136 | fi 137 | if test -z "$use_gpgrt_config"; then 138 | if test x"${LIBGCRYPT_CONFIG}" = x ; then 139 | case "${SYSROOT}" in 140 | /*) 141 | if test -x "${SYSROOT}/bin/libgcrypt-config" ; then 142 | LIBGCRYPT_CONFIG="${SYSROOT}/bin/libgcrypt-config" 143 | fi 144 | ;; 145 | '') 146 | ;; 147 | *) 148 | AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.]) 149 | ;; 150 | esac 151 | fi 152 | AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no) 153 | fi 154 | 155 | tmp=ifelse([$1], ,1:1.2.0,$1) 156 | if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then 157 | req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` 158 | min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` 159 | else 160 | req_libgcrypt_api=0 161 | min_libgcrypt_version="$tmp" 162 | fi 163 | 164 | AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version) 165 | ok=no 166 | if test "$LIBGCRYPT_CONFIG" != "no" ; then 167 | req_major=`echo $min_libgcrypt_version | \ 168 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` 169 | req_minor=`echo $min_libgcrypt_version | \ 170 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` 171 | req_micro=`echo $min_libgcrypt_version | \ 172 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` 173 | if test -z "$use_gpgrt_config"; then 174 | libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version` 175 | else 176 | libgcrypt_config_version=`$LIBGCRYPT_CONFIG --modversion` 177 | fi 178 | major=`echo $libgcrypt_config_version | \ 179 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` 180 | minor=`echo $libgcrypt_config_version | \ 181 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` 182 | micro=`echo $libgcrypt_config_version | \ 183 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` 184 | if test "$major" -gt "$req_major"; then 185 | ok=yes 186 | else 187 | if test "$major" -eq "$req_major"; then 188 | if test "$minor" -gt "$req_minor"; then 189 | ok=yes 190 | else 191 | if test "$minor" -eq "$req_minor"; then 192 | if test "$micro" -ge "$req_micro"; then 193 | ok=yes 194 | fi 195 | fi 196 | fi 197 | fi 198 | fi 199 | fi 200 | if test $ok = yes; then 201 | AC_MSG_RESULT([yes ($libgcrypt_config_version)]) 202 | else 203 | AC_MSG_RESULT(no) 204 | fi 205 | if test $ok = yes; then 206 | # If we have a recent libgcrypt, we should also check that the 207 | # API is compatible 208 | if test "$req_libgcrypt_api" -gt 0 ; then 209 | if test -z "$use_gpgrt_config"; then 210 | tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0` 211 | else 212 | tmp=`$LIBGCRYPT_CONFIG --variable=api_version 2>/dev/null || echo 0` 213 | fi 214 | if test "$tmp" -gt 0 ; then 215 | AC_MSG_CHECKING([LIBGCRYPT API version]) 216 | if test "$req_libgcrypt_api" -eq "$tmp" ; then 217 | AC_MSG_RESULT([okay]) 218 | else 219 | ok=no 220 | AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp]) 221 | fi 222 | fi 223 | fi 224 | fi 225 | if test $ok = yes; then 226 | LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` 227 | LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` 228 | ifelse([$2], , :, [$2]) 229 | if test -z "$use_gpgrt_config"; then 230 | libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none` 231 | else 232 | libgcrypt_config_host=`$LIBGCRYPT_CONFIG --variable=host 2>/dev/null || echo none` 233 | fi 234 | if test x"$libgcrypt_config_host" != xnone ; then 235 | if test x"$libgcrypt_config_host" != x"$host" ; then 236 | AC_MSG_WARN([[ 237 | *** 238 | *** The config script "$LIBGCRYPT_CONFIG" was 239 | *** built for $libgcrypt_config_host and thus may not match the 240 | *** used host $host. 241 | *** You may want to use the configure option --with-libgcrypt-prefix 242 | *** to specify a matching config script or use \$SYSROOT. 243 | ***]]) 244 | gpg_config_script_warn="$gpg_config_script_warn libgcrypt" 245 | fi 246 | fi 247 | else 248 | LIBGCRYPT_CFLAGS="" 249 | LIBGCRYPT_LIBS="" 250 | ifelse([$3], , :, [$3]) 251 | fi 252 | AC_SUBST(LIBGCRYPT_CFLAGS) 253 | AC_SUBST(LIBGCRYPT_LIBS) 254 | ]) 255 | -------------------------------------------------------------------------------- /src/ciphersuites.h: -------------------------------------------------------------------------------- 1 | /* ciphersuites.h - cipher suite definitions 2 | * Copyright (C) 2006-2014, Brainspark B.V. 3 | * Copyright (C) 2014 g10 code GmbH 4 | * 5 | * This file is part of NTBTLS 6 | * 7 | * NTBTLS is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * NTBTLS is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, see . 19 | * 20 | * This file was part of PolarSSL (http://www.polarssl.org). Former 21 | * Lead Maintainer: Paul Bakker . 22 | * Please do not file bug reports to them but to the address given in 23 | * the file AUTHORS in the top directory of NTBTLS. 24 | */ 25 | 26 | #ifndef NTBTLS_CIPHERSUITES_H 27 | #define NTBTLS_CIPHERSUITES_H 28 | 29 | 30 | /* 31 | * Supported ciphersuites (Official IANA names) 32 | */ 33 | #define TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x0A 34 | 35 | #define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x16 36 | 37 | #define TLS_RSA_WITH_AES_128_CBC_SHA 0x2F 38 | 39 | #define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x33 40 | #define TLS_RSA_WITH_AES_256_CBC_SHA 0x35 41 | #define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x39 42 | 43 | #define TLS_RSA_WITH_AES_128_CBC_SHA256 0x3C /**< TLS 1.2 */ 44 | #define TLS_RSA_WITH_AES_256_CBC_SHA256 0x3D /**< TLS 1.2 */ 45 | 46 | #define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x41 47 | #define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x45 48 | 49 | #define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x67 /**< TLS 1.2 */ 50 | #define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x6B /**< TLS 1.2 */ 51 | 52 | #define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x84 53 | #define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x88 54 | 55 | #define TLS_PSK_WITH_3DES_EDE_CBC_SHA 0x8B 56 | #define TLS_PSK_WITH_AES_128_CBC_SHA 0x8C 57 | #define TLS_PSK_WITH_AES_256_CBC_SHA 0x8D 58 | 59 | #define TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA 0x8F 60 | #define TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x90 61 | #define TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x91 62 | 63 | #define TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA 0x93 64 | #define TLS_RSA_PSK_WITH_AES_128_CBC_SHA 0x94 65 | #define TLS_RSA_PSK_WITH_AES_256_CBC_SHA 0x95 66 | 67 | #define TLS_RSA_WITH_AES_128_GCM_SHA256 0x9C /**< TLS 1.2 */ 68 | #define TLS_RSA_WITH_AES_256_GCM_SHA384 0x9D /**< TLS 1.2 */ 69 | #define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x9E /**< TLS 1.2 */ 70 | #define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x9F /**< TLS 1.2 */ 71 | 72 | #define TLS_PSK_WITH_AES_128_GCM_SHA256 0xA8 /**< TLS 1.2 */ 73 | #define TLS_PSK_WITH_AES_256_GCM_SHA384 0xA9 /**< TLS 1.2 */ 74 | #define TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 0xAA /**< TLS 1.2 */ 75 | #define TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 0xAB /**< TLS 1.2 */ 76 | #define TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 0xAC /**< TLS 1.2 */ 77 | #define TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 0xAD /**< TLS 1.2 */ 78 | 79 | #define TLS_PSK_WITH_AES_128_CBC_SHA256 0xAE 80 | #define TLS_PSK_WITH_AES_256_CBC_SHA384 0xAF 81 | 82 | #define TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 0xB2 83 | #define TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 0xB3 84 | 85 | #define TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 0xB6 86 | #define TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 0xB7 87 | 88 | #define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBA /**< TLS 1.2 */ 89 | #define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBE /**< TLS 1.2 */ 90 | 91 | #define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC0 /**< TLS 1.2 */ 92 | #define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4 /**< TLS 1.2 */ 93 | 94 | #define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 /**< Not in SSL3! */ 95 | #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /**< Not in SSL3! */ 96 | #define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /**< Not in SSL3! */ 97 | 98 | #define TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 /**< Not in SSL3! */ 99 | #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /**< Not in SSL3! */ 100 | #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /**< Not in SSL3! */ 101 | 102 | #define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D /**< Not in SSL3! */ 103 | #define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /**< Not in SSL3! */ 104 | #define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /**< Not in SSL3! */ 105 | 106 | #define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /**< Not in SSL3! */ 107 | #define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 /**< Not in SSL3! */ 108 | #define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 /**< Not in SSL3! */ 109 | 110 | #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /**< TLS 1.2 */ 111 | #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /**< TLS 1.2 */ 112 | #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /**< TLS 1.2 */ 113 | #define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /**< TLS 1.2 */ 114 | #define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /**< TLS 1.2 */ 115 | #define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /**< TLS 1.2 */ 116 | #define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /**< TLS 1.2 */ 117 | #define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /**< TLS 1.2 */ 118 | 119 | #define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /**< TLS 1.2 */ 120 | #define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /**< TLS 1.2 */ 121 | #define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /**< TLS 1.2 */ 122 | #define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /**< TLS 1.2 */ 123 | #define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /**< TLS 1.2 */ 124 | #define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /**< TLS 1.2 */ 125 | #define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /**< TLS 1.2 */ 126 | #define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /**< TLS 1.2 */ 127 | 128 | #define TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 0xC034 /**< Not in SSL3! */ 129 | #define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA 0xC035 /**< Not in SSL3! */ 130 | #define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA 0xC036 /**< Not in SSL3! */ 131 | #define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037 /**< Not in SSL3! */ 132 | #define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0xC038 /**< Not in SSL3! */ 133 | 134 | #define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< Not in SSL3! */ 135 | #define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< Not in SSL3! */ 136 | #define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC074 /**< Not in SSL3! */ 137 | #define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC075 /**< Not in SSL3! */ 138 | #define TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC076 /**< Not in SSL3! */ 139 | #define TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC077 /**< Not in SSL3! */ 140 | #define TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC078 /**< Not in SSL3! */ 141 | #define TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC079 /**< Not in SSL3! */ 142 | 143 | #define TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07A /**< TLS 1.2 */ 144 | #define TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07B /**< TLS 1.2 */ 145 | #define TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07C /**< TLS 1.2 */ 146 | #define TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07D /**< TLS 1.2 */ 147 | #define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC086 /**< TLS 1.2 */ 148 | #define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC087 /**< TLS 1.2 */ 149 | #define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC088 /**< TLS 1.2 */ 150 | #define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC089 /**< TLS 1.2 */ 151 | #define TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08A /**< TLS 1.2 */ 152 | #define TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08B /**< TLS 1.2 */ 153 | #define TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08C /**< TLS 1.2 */ 154 | #define TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08D /**< TLS 1.2 */ 155 | 156 | #define TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC08E /**< TLS 1.2 */ 157 | #define TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC08F /**< TLS 1.2 */ 158 | #define TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC090 /**< TLS 1.2 */ 159 | #define TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC091 /**< TLS 1.2 */ 160 | #define TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC092 /**< TLS 1.2 */ 161 | #define TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC093 /**< TLS 1.2 */ 162 | 163 | #define TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC094 164 | #define TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC095 165 | #define TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC096 166 | #define TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC097 167 | #define TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC098 168 | #define TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC099 169 | #define TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC09A /**< Not in SSL3! */ 170 | #define TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC09B /**< Not in SSL3! */ 171 | 172 | #define TLS_RSA_WITH_AES_128_CCM 0xC09C /**< TLS 1.2 */ 173 | #define TLS_RSA_WITH_AES_256_CCM 0xC09D /**< TLS 1.2 */ 174 | #define TLS_DHE_RSA_WITH_AES_128_CCM 0xC09E /**< TLS 1.2 */ 175 | #define TLS_DHE_RSA_WITH_AES_256_CCM 0xC09F /**< TLS 1.2 */ 176 | #define TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 /**< TLS 1.2 */ 177 | #define TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 /**< TLS 1.2 */ 178 | #define TLS_DHE_RSA_WITH_AES_128_CCM_8 0xC0A2 /**< TLS 1.2 */ 179 | #define TLS_DHE_RSA_WITH_AES_256_CCM_8 0xC0A3 /**< TLS 1.2 */ 180 | #define TLS_PSK_WITH_AES_128_CCM 0xC0A4 /**< TLS 1.2 */ 181 | #define TLS_PSK_WITH_AES_256_CCM 0xC0A5 /**< TLS 1.2 */ 182 | #define TLS_DHE_PSK_WITH_AES_128_CCM 0xC0A6 /**< TLS 1.2 */ 183 | #define TLS_DHE_PSK_WITH_AES_256_CCM 0xC0A7 /**< TLS 1.2 */ 184 | #define TLS_PSK_WITH_AES_128_CCM_8 0xC0A8 /**< TLS 1.2 */ 185 | #define TLS_PSK_WITH_AES_256_CCM_8 0xC0A9 /**< TLS 1.2 */ 186 | #define TLS_DHE_PSK_WITH_AES_128_CCM_8 0xC0AA /**< TLS 1.2 */ 187 | #define TLS_DHE_PSK_WITH_AES_256_CCM_8 0xC0AB /**< TLS 1.2 */ 188 | /* The last two are named with PSK_DHE in the RFC, which looks like a typo */ 189 | 190 | #define TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC /**< TLS 1.2 */ 191 | #define TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD /**< TLS 1.2 */ 192 | #define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */ 193 | #define TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */ 194 | 195 | #define CIPHERSUITE_FLAG_SHORT_TAG 0x01 /* Short authentication tag. */ 196 | 197 | const int *_ntbtls_ciphersuite_list (void); 198 | ciphersuite_t _ntbtls_ciphersuite_from_id (int suite_id); 199 | 200 | const char *_ntbtls_ciphersuite_get_name (int suite_id); 201 | 202 | cipher_algo_t _ntbtls_ciphersuite_get_cipher (ciphersuite_t suite, 203 | cipher_mode_t *r_mode); 204 | mac_algo_t _ntbtls_ciphersuite_get_mac (ciphersuite_t suite); 205 | key_exchange_type_t _ntbtls_ciphersuite_get_kex (ciphersuite_t suite); 206 | unsigned int _ntbtls_ciphersuite_get_flags (ciphersuite_t suite); 207 | pk_algo_t _ntbtls_ciphersuite_get_sig_pk_alg (ciphersuite_t suite); 208 | int _ntbtls_ciphersuite_version_ok (ciphersuite_t suite, 209 | int min_minor_ver, int max_minor_ver); 210 | 211 | int _ntbtls_ciphersuite_uses_ec (ciphersuite_t suite); 212 | int _ntbtls_ciphersuite_uses_psk (ciphersuite_t suite); 213 | 214 | 215 | #endif /*NTBTLS_CIPHERSUITES_H*/ 216 | -------------------------------------------------------------------------------- /src/ntbtls-cli.c: -------------------------------------------------------------------------------- 1 | /* ntbtls-cli.h - NTBTLS client test program 2 | * Copyright (C) 2014 g10 Code GmbH 3 | * 4 | * This file is part of NTBTLS 5 | * 6 | * NTBTLS is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * NTBTLS is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #ifdef HAVE_W32_SYSTEM 30 | # define WIN32_LEAN_AND_MEAN 31 | # ifdef HAVE_WINSOCK2_H 32 | # include 33 | # endif 34 | # include 35 | #else 36 | # include 37 | # include 38 | # include 39 | # include 40 | #endif 41 | 42 | #include "ntbtls.h" 43 | 44 | #define PGMNAME "ntbtls-cli" 45 | 46 | static int verbose; 47 | static int errorcount; 48 | static char *opt_hostname; 49 | static int opt_head; 50 | 51 | 52 | 53 | /* 54 | * Reporting functions. 55 | */ 56 | static void 57 | die (const char *format, ...) 58 | { 59 | va_list arg_ptr ; 60 | 61 | fflush (stdout); 62 | #ifdef HAVE_FLOCKFILE 63 | flockfile (stderr); 64 | #endif 65 | fprintf (stderr, "%s: ", PGMNAME); 66 | va_start (arg_ptr, format) ; 67 | vfprintf (stderr, format, arg_ptr); 68 | va_end (arg_ptr); 69 | if (*format && format[strlen(format)-1] != '\n') 70 | putc ('\n', stderr); 71 | #ifdef HAVE_FLOCKFILE 72 | funlockfile (stderr); 73 | #endif 74 | exit (1); 75 | } 76 | 77 | 78 | static void 79 | fail (const char *format, ...) 80 | { 81 | va_list arg_ptr; 82 | 83 | fflush (stdout); 84 | #ifdef HAVE_FLOCKFILE 85 | flockfile (stderr); 86 | #endif 87 | fprintf (stderr, "%s: ", PGMNAME); 88 | va_start (arg_ptr, format); 89 | vfprintf (stderr, format, arg_ptr); 90 | va_end (arg_ptr); 91 | if (*format && format[strlen(format)-1] != '\n') 92 | putc ('\n', stderr); 93 | #ifdef HAVE_FLOCKFILE 94 | funlockfile (stderr); 95 | #endif 96 | errorcount++; 97 | if (errorcount >= 50) 98 | die ("stopped after 50 errors."); 99 | } 100 | 101 | 102 | static void 103 | info (const char *format, ...) 104 | { 105 | va_list arg_ptr; 106 | 107 | if (!verbose) 108 | return; 109 | #ifdef HAVE_FLOCKFILE 110 | flockfile (stderr); 111 | #endif 112 | fprintf (stderr, "%s: ", PGMNAME); 113 | va_start (arg_ptr, format); 114 | vfprintf (stderr, format, arg_ptr); 115 | if (*format && format[strlen(format)-1] != '\n') 116 | putc ('\n', stderr); 117 | va_end (arg_ptr); 118 | #ifdef HAVE_FLOCKFILE 119 | funlockfile (stderr); 120 | #endif 121 | } 122 | 123 | 124 | 125 | /* Until we support send/recv in estream we need to use es_fopencookie 126 | * under Windows. */ 127 | #ifdef HAVE_W32_SYSTEM 128 | static gpgrt_ssize_t 129 | w32_cookie_read (void *cookie, void *buffer, size_t size) 130 | { 131 | int sock = (int)cookie; 132 | int nread; 133 | 134 | do 135 | { 136 | /* Under Windows we need to use recv for a socket. */ 137 | nread = recv (sock, buffer, size, 0); 138 | } 139 | while (nread == -1 && errno == EINTR); 140 | 141 | return (gpgrt_ssize_t)nread; 142 | } 143 | 144 | static gpg_error_t 145 | w32_write_server (int sock, const char *data, size_t length) 146 | { 147 | int nleft; 148 | int nwritten; 149 | 150 | nleft = length; 151 | while (nleft > 0) 152 | { 153 | nwritten = send (sock, data, nleft, 0); 154 | if ( nwritten == SOCKET_ERROR ) 155 | { 156 | info ("network write failed: ec=%d\n", (int)WSAGetLastError ()); 157 | return gpg_error (GPG_ERR_NETWORK); 158 | } 159 | nleft -= nwritten; 160 | data += nwritten; 161 | } 162 | 163 | return 0; 164 | } 165 | 166 | /* Write handler for estream. */ 167 | static gpgrt_ssize_t 168 | w32_cookie_write (void *cookie, const void *buffer_arg, size_t size) 169 | { 170 | int sock = (int)cookie; 171 | const char *buffer = buffer_arg; 172 | int nwritten = 0; 173 | 174 | if (w32_write_server (sock, buffer, size)) 175 | { 176 | gpg_err_set_errno (EIO); 177 | nwritten = -1; 178 | } 179 | else 180 | nwritten = size; 181 | 182 | return (gpgrt_ssize_t)nwritten; 183 | } 184 | 185 | static es_cookie_io_functions_t w32_cookie_functions = 186 | { 187 | w32_cookie_read, 188 | w32_cookie_write, 189 | NULL, 190 | NULL 191 | }; 192 | #endif /*HAVE_W32_SYSTEM*/ 193 | 194 | 195 | 196 | static int 197 | connect_server (const char *server, unsigned short port) 198 | { 199 | gpg_error_t err; 200 | int sock = -1; 201 | struct sockaddr_in addr; 202 | struct hostent *host; 203 | union { 204 | char *addr; 205 | struct in_addr *in_addr; 206 | } addru; 207 | 208 | addr.sin_family = AF_INET; 209 | addr.sin_port = htons (port); 210 | host = gethostbyname ((char*)server); 211 | if (!host) 212 | { 213 | err = gpg_error_from_syserror (); 214 | fail ("host '%s' not found: %s\n", server, gpg_strerror (err)); 215 | return -1; 216 | } 217 | 218 | addru.addr = host->h_addr; 219 | addr.sin_addr = *addru.in_addr; 220 | 221 | sock = socket (AF_INET, SOCK_STREAM, 0); 222 | if (sock == -1) 223 | { 224 | err = gpg_error_from_syserror (); 225 | die ("error creating socket: %s\n", gpg_strerror (err)); 226 | return -1; 227 | } 228 | 229 | if (connect (sock, (struct sockaddr *)&addr, sizeof addr) == -1) 230 | { 231 | err = gpg_error_from_syserror (); 232 | fail ("error connecting '%s': %s\n", server, gpg_strerror (err)); 233 | close (sock); 234 | return -1; 235 | } 236 | 237 | info ("connected to '%s' port %hu\n", server, port); 238 | 239 | return sock; 240 | } 241 | 242 | 243 | static int 244 | connect_estreams (const char *server, int port, 245 | estream_t *r_in, estream_t *r_out) 246 | { 247 | gpg_error_t err; 248 | int sock; 249 | 250 | *r_in = *r_out = NULL; 251 | 252 | sock = connect_server (server, port); 253 | if (sock == -1) 254 | return gpg_error (GPG_ERR_GENERAL); 255 | 256 | #ifdef HAVE_W32_SYSTEM 257 | *r_in = es_fopencookie ((void*)(unsigned int)sock, "rb", 258 | w32_cookie_functions); 259 | #else 260 | *r_in = es_fdopen (sock, "rb"); 261 | #endif 262 | if (!*r_in) 263 | { 264 | err = gpg_error_from_syserror (); 265 | close (sock); 266 | return err; 267 | } 268 | #ifdef HAVE_W32_SYSTEM 269 | *r_out = es_fopencookie ((void*)(unsigned int)sock, "wb", 270 | w32_cookie_functions); 271 | #else 272 | *r_out = es_fdopen (sock, "wb"); 273 | #endif 274 | if (!*r_out) 275 | { 276 | err = gpg_error_from_syserror (); 277 | es_fclose (*r_in); 278 | *r_in = NULL; 279 | close (sock); 280 | return err; 281 | } 282 | 283 | return 0; 284 | } 285 | 286 | 287 | 288 | static void 289 | simple_client (const char *server, int port) 290 | { 291 | gpg_error_t err; 292 | ntbtls_t tls; 293 | estream_t inbound, outbound; 294 | estream_t readfp, writefp; 295 | int c; 296 | 297 | err = ntbtls_new (&tls, NTBTLS_CLIENT); 298 | if (err) 299 | die ("ntbtls_init failed: %s <%s>\n", 300 | gpg_strerror (err), gpg_strsource (err)); 301 | 302 | err = connect_estreams (server, port, &inbound, &outbound); 303 | if (err) 304 | die ("error connecting server: %s <%s>\n", 305 | gpg_strerror (err), gpg_strsource (err)); 306 | 307 | err = ntbtls_set_transport (tls, inbound, outbound); 308 | if (err) 309 | die ("ntbtls_set_transport failed: %s <%s>\n", 310 | gpg_strerror (err), gpg_strsource (err)); 311 | 312 | err = ntbtls_get_stream (tls, &readfp, &writefp); 313 | if (err) 314 | die ("ntbtls_get_stream failed: %s <%s>\n", 315 | gpg_strerror (err), gpg_strsource (err)); 316 | 317 | if (opt_hostname) 318 | { 319 | err = ntbtls_set_hostname (tls, opt_hostname); 320 | if (err) 321 | die ("ntbtls_set_hostname failed: %s <%s>\n", 322 | gpg_strerror (err), gpg_strsource (err)); 323 | } 324 | 325 | info ("starting handshake"); 326 | while ((err = ntbtls_handshake (tls))) 327 | { 328 | const char *s; 329 | 330 | if ((s = ntbtls_get_last_alert (tls, NULL, NULL))) 331 | info ("received alert: %s", s); 332 | info ("handshake error: %s <%s>", gpg_strerror (err),gpg_strsource (err)); 333 | switch (gpg_err_code (err)) 334 | { 335 | default: 336 | break; 337 | } 338 | die ("handshake failed"); 339 | } 340 | info ("handshake done"); 341 | 342 | do 343 | { 344 | es_fprintf (writefp, "%s / HTTP/1.0\r\n", opt_head? "HEAD":"GET"); 345 | if (opt_hostname) 346 | es_fprintf (writefp, "Host: %s\r\n", opt_hostname); 347 | es_fprintf (writefp, "X-ntbtls: %s\r\n", 348 | ntbtls_check_version (PACKAGE_VERSION)); 349 | es_fputs ("\r\n", writefp); 350 | es_fflush (writefp); 351 | while (/*es_pending (readfp) &&*/ (c = es_fgetc (readfp)) != EOF) 352 | putchar (c); 353 | } 354 | while (c != EOF); 355 | 356 | ntbtls_release (tls); 357 | es_fclose (inbound); 358 | es_fclose (outbound); 359 | } 360 | 361 | 362 | 363 | int 364 | main (int argc, char **argv) 365 | { 366 | int last_argc = -1; 367 | int debug_level = 0; 368 | int port = 443; 369 | char *host; 370 | 371 | if (argc) 372 | { argc--; argv++; } 373 | while (argc && last_argc != argc ) 374 | { 375 | last_argc = argc; 376 | if (!strcmp (*argv, "--")) 377 | { 378 | argc--; argv++; 379 | break; 380 | } 381 | else if (!strcmp (*argv, "--help")) 382 | { 383 | fputs ("Usage: " PGMNAME " [OPTIONS] HOST\n" 384 | "Connect via TLS to HOST\n" 385 | "Options:\n" 386 | " --version print the library version\n" 387 | " --verbose show more diagnostics\n" 388 | " --debug LEVEL enable debugging at LEVEL\n" 389 | " --port N connect to port N (default is 443)\n" 390 | " --hostname NAME use NAME instead of HOST for SNI\n" 391 | " --head send a HEAD and not a GET request\n" 392 | "\n", stdout); 393 | return 0; 394 | } 395 | else if (!strcmp (*argv, "--version")) 396 | { 397 | printf ("%s\n", ntbtls_check_version (NULL)); 398 | if (verbose) 399 | printf ("%s", ntbtls_check_version ("\001\001")); 400 | return 0; 401 | } 402 | else if (!strcmp (*argv, "--verbose")) 403 | { 404 | verbose = 1; 405 | argc--; argv++; 406 | } 407 | else if (!strcmp (*argv, "--debug")) 408 | { 409 | verbose = 1; 410 | argc--; argv++; 411 | if (argc) 412 | { 413 | debug_level = atoi (*argv); 414 | argc--; argv++; 415 | } 416 | else 417 | debug_level = 1; 418 | } 419 | else if (!strcmp (*argv, "--port")) 420 | { 421 | argc--; argv++; 422 | if (argc) 423 | { 424 | port = atoi (*argv); 425 | argc--; argv++; 426 | } 427 | else 428 | port = 8443; 429 | } 430 | else if (!strcmp (*argv, "--hostname")) 431 | { 432 | if (argc < 2) 433 | die ("argument missing for option '%s'\n", *argv); 434 | argc--; argv++; 435 | opt_hostname = *argv; 436 | argc--; argv++; 437 | } 438 | else if (!strcmp (*argv, "--head")) 439 | { 440 | opt_head = 1; 441 | argc--; argv++; 442 | } 443 | else if (!strncmp (*argv, "--", 2) && (*argv)[2]) 444 | die ("Invalid option '%s'\n", *argv); 445 | } 446 | 447 | host = argc? *argv : "localhost"; 448 | if (!opt_hostname) 449 | opt_hostname = host; 450 | if (!*opt_hostname) 451 | opt_hostname = NULL; 452 | 453 | #ifdef HAVE_W32_SYSTEM 454 | { 455 | WSADATA wsadat; 456 | WSAStartup (0x202, &wsadat); 457 | } 458 | #endif 459 | 460 | if (!ntbtls_check_version (PACKAGE_VERSION)) 461 | die ("NTBTLS library too old (need %s, have %s)\n", 462 | PACKAGE_VERSION, ntbtls_check_version (NULL)); 463 | 464 | if (debug_level) 465 | ntbtls_set_debug (debug_level, NULL, NULL); 466 | 467 | simple_client (host, port); 468 | return 0; 469 | } 470 | -------------------------------------------------------------------------------- /src/ecdh.c: -------------------------------------------------------------------------------- 1 | /* ecdh.c - EC Diffie-Hellman key exchange 2 | * Copyright (C) 2014, 2017 g10 Code GmbH 3 | * 4 | * This file is part of NTBTLS 5 | * 6 | * NTBTLS is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * NTBTLS is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "ntbtls-int.h" 27 | 28 | 29 | /* While running the validation function we need to keep track of the 30 | * certificates and the validation outcome of each. We use this type 31 | * for it. */ 32 | struct ecdh_context_s 33 | { 34 | const char *curve_name; /* Only for display purposes. */ 35 | gcry_ctx_t ecctx; /* The initialized context for the curve. 36 | * This also holds the secre D and our 37 | * public key Q. */ 38 | gcry_mpi_point_t Qpeer; /* The peer's public value */ 39 | }; 40 | 41 | 42 | 43 | /* Create a new ECDH context. */ 44 | gpg_error_t 45 | _ntbtls_ecdh_new (ecdh_context_t *r_ecdh) 46 | { 47 | ecdh_context_t ecdh; 48 | 49 | *r_ecdh = NULL; 50 | 51 | ecdh = calloc (1, sizeof *ecdh); 52 | if (!ecdh) 53 | return gpg_error_from_syserror (); 54 | 55 | *r_ecdh = ecdh; 56 | 57 | return 0; 58 | } 59 | 60 | 61 | /* Release an ECDH context. */ 62 | void 63 | _ntbtls_ecdh_release (ecdh_context_t ecdh) 64 | { 65 | if (!ecdh) 66 | return; 67 | gcry_ctx_release (ecdh->ecctx); 68 | gcry_mpi_point_release (ecdh->Qpeer); 69 | free (ecdh); 70 | } 71 | 72 | 73 | /* Parse the TLS ECDHE parameters and store them in ECDH. DER is the 74 | * buffer with the params of length DERLEN. The number of actual 75 | * parsed bytes is stored at R_NPARSED. */ 76 | gpg_error_t 77 | _ntbtls_ecdh_read_params (ecdh_context_t ecdh, 78 | const void *_der, size_t derlen, 79 | size_t *r_nparsed) 80 | { 81 | gpg_error_t err; 82 | const unsigned char *derstart = _der; 83 | const unsigned char *der = _der; 84 | size_t n; 85 | gcry_mpi_t tmpmpi; 86 | 87 | if (r_nparsed) 88 | *r_nparsed = 0; 89 | 90 | if (!ecdh || !der) 91 | return gpg_error (GPG_ERR_INV_ARG); 92 | 93 | ecdh->curve_name = NULL; 94 | gcry_ctx_release (ecdh->ecctx); ecdh->ecctx = NULL; 95 | gcry_mpi_point_release (ecdh->Qpeer); ecdh->Qpeer = NULL; 96 | 97 | /* struct { 98 | * ECParameters curve_params; 99 | * ECPoint public; 100 | * } ServerECDHParams; 101 | */ 102 | 103 | /* Parse ECParameters. */ 104 | if (derlen < 3) 105 | return gpg_error (GPG_ERR_TOO_SHORT); 106 | /* We only support named curves (3). */ 107 | if (*der != 3) 108 | return gpg_error (GPG_ERR_UNKNOWN_CURVE); 109 | der++; 110 | derlen--; 111 | 112 | switch (buf16_to_uint (der)) 113 | { 114 | case 23: ecdh->curve_name = "secp256r1"; break; 115 | case 24: ecdh->curve_name = "secp384r1"; break; 116 | case 25: ecdh->curve_name = "secp521r1"; break; 117 | case 26: ecdh->curve_name = "brainpoolP256r1"; break; 118 | case 27: ecdh->curve_name = "brainpoolP384r1"; break; 119 | case 28: ecdh->curve_name = "brainpoolP512r1"; break; 120 | #ifdef SUPPORT_X25519 121 | case 29: ecdh->curve_name = "X25519"; break; 122 | #endif 123 | #ifdef SUPPORT_X448 124 | case 30: ecdh->curve_name = "X448"; break; 125 | #endif 126 | default: 127 | return gpg_error (GPG_ERR_UNKNOWN_CURVE); 128 | } 129 | der += 2; 130 | derlen -= 2; 131 | 132 | err = gcry_mpi_ec_new (&ecdh->ecctx, NULL, ecdh->curve_name); 133 | if (err) 134 | return err; 135 | 136 | /* Parse ECPoint. */ 137 | if (derlen < 2) 138 | return gpg_error (GPG_ERR_TOO_SHORT); 139 | n = *der++; derlen--; 140 | if (!n) 141 | return gpg_error (GPG_ERR_INV_OBJ); 142 | if (n > derlen) 143 | return gpg_error (GPG_ERR_TOO_LARGE); 144 | 145 | tmpmpi = gcry_mpi_set_opaque_copy (NULL, der, 8*n); 146 | if (!tmpmpi) 147 | return gpg_error_from_syserror (); 148 | der += n; 149 | derlen -= n; 150 | 151 | ecdh->Qpeer = gcry_mpi_point_new (0); 152 | err = gcry_mpi_ec_decode_point (ecdh->Qpeer, tmpmpi, ecdh->ecctx); 153 | gcry_mpi_release (tmpmpi); 154 | if (err) 155 | { 156 | gcry_mpi_point_release (ecdh->Qpeer); 157 | ecdh->Qpeer = NULL; 158 | return err; 159 | } 160 | 161 | if (r_nparsed) 162 | *r_nparsed = (der - derstart); 163 | 164 | debug_msg (3, "ECDH curve: %s", ecdh->curve_name); 165 | if (ecdh->curve_name[0] != 'X') 166 | debug_pnt (3, "ECDH Qpeer", ecdh->Qpeer, ecdh->ecctx); 167 | /* FIXME: debug print the point for Montgomery curve. */ 168 | 169 | return 0; 170 | } 171 | 172 | 173 | /* Generate the secret D with 0 < D < N. */ 174 | static gcry_mpi_t 175 | gen_d (ecdh_context_t ecdh) 176 | { 177 | unsigned int nbits; 178 | gcry_mpi_t n, d; 179 | 180 | if (ecdh->curve_name[0] == 'X') 181 | { 182 | gcry_mpi_t p; 183 | unsigned int pbits; 184 | void *rnd; 185 | int len; 186 | 187 | p = gcry_mpi_ec_get_mpi ("p", ecdh->ecctx, 0); 188 | if (!p) 189 | return NULL; 190 | pbits = gcry_mpi_get_nbits (p); 191 | len = (pbits+7)/8; 192 | gcry_mpi_release (p); 193 | 194 | rnd = gcry_random_bytes_secure (len, GCRY_STRONG_RANDOM); 195 | d = gcry_mpi_set_opaque (NULL, rnd, pbits); 196 | return d; 197 | } 198 | 199 | n = gcry_mpi_ec_get_mpi ("n", ecdh->ecctx, 0); 200 | if (!n) 201 | return NULL; 202 | nbits = gcry_mpi_get_nbits (n); 203 | d = gcry_mpi_snew (nbits); 204 | 205 | for (;;) 206 | { 207 | /* FIXME: For the second and further iterations we use too much 208 | * random. It would be better to get just a few bits and use 209 | * set/clear_bit to insert that into the D. Or implement a 210 | * suitable gen_d function in libgcrypt. */ 211 | gcry_mpi_randomize (d, nbits, GCRY_STRONG_RANDOM); 212 | 213 | /* Make sure we have the requested number of bits. The code 214 | * looks a bit weird but it is easy to understand if you 215 | * consider that mpi_set_highbit clears all higher bits. */ 216 | if (mpi_test_bit (d, nbits-1)) 217 | mpi_set_highbit (d, nbits-1); 218 | else 219 | mpi_clear_highbit (d, nbits-1); 220 | 221 | if (mpi_cmp (d, n) < 0 /* check: D < N */ 222 | && mpi_cmp_ui (d, 0) > 0) /* check: D > 0 */ 223 | break; /* okay */ 224 | } 225 | 226 | gcry_mpi_release (n); 227 | return d; 228 | } 229 | 230 | 231 | /* Create our own private value D and a public key. Store the public 232 | key in OUTBUF. OUTBUFSIZE is the available length of OUTBUF. On 233 | success the actual length of OUTBUF is stored at R_OUTBUFLEN. */ 234 | gpg_error_t 235 | _ntbtls_ecdh_make_public (ecdh_context_t ecdh, 236 | unsigned char *outbuf, size_t outbufsize, 237 | size_t *r_outbuflen) 238 | { 239 | gpg_error_t err; 240 | size_t n; 241 | 242 | if (!ecdh || !outbuf || !r_outbuflen || outbufsize < 2) 243 | return gpg_error (GPG_ERR_INV_ARG); 244 | 245 | *r_outbuflen = 0; 246 | 247 | if (!ecdh->curve_name || !ecdh->ecctx || !ecdh->Qpeer) 248 | return gpg_error (GPG_ERR_NOT_INITIALIZED); 249 | 250 | /* Create a secret and store it in the context. */ 251 | { 252 | gcry_mpi_t d; 253 | 254 | d = gen_d (ecdh); 255 | if (!d) 256 | return gpg_error (GPG_ERR_INV_OBJ); 257 | 258 | gcry_mpi_ec_set_mpi ("d", d, ecdh->ecctx); 259 | debug_mpi (3, "ECDH d ", d); 260 | gcry_mpi_release (d); 261 | } 262 | 263 | if (ecdh->curve_name[0] == 'X') 264 | { 265 | gcry_mpi_t p; 266 | unsigned int pbits; 267 | gcry_mpi_point_t Q; 268 | gcry_mpi_t x; 269 | int i; 270 | int len; 271 | 272 | p = gcry_mpi_ec_get_mpi ("p", ecdh->ecctx, 0); 273 | if (!p) 274 | return gpg_error (GPG_ERR_INTERNAL); 275 | pbits = gcry_mpi_get_nbits (p); 276 | len = (pbits+7)/8; 277 | gcry_mpi_release (p); 278 | if (len > 255) 279 | return gpg_error (GPG_ERR_INV_DATA); 280 | 281 | x = gcry_mpi_new (0); 282 | Q = gcry_mpi_ec_get_point ("q", ecdh->ecctx, 0); 283 | if (!Q) 284 | { 285 | gcry_mpi_release (x); 286 | return gpg_error (GPG_ERR_INTERNAL); 287 | } 288 | if (gcry_mpi_ec_get_affine (x, NULL, Q, ecdh->ecctx)) 289 | { 290 | gcry_mpi_point_release (Q); 291 | return gpg_error (GPG_ERR_INV_DATA); 292 | } 293 | 294 | gcry_mpi_point_release (Q); 295 | debug_mpi (3, "ECDH Qour (in big-endian)", x); 296 | 297 | err = gcry_mpi_print (GCRYMPI_FMT_USG, outbuf+1, outbufsize-1, &n, x); 298 | gcry_mpi_release (x); 299 | if (err) 300 | return err; 301 | /* Fill zero, if shorter. */ 302 | if (n < len) 303 | { 304 | memmove (outbuf+1+len-n, outbuf+1, n); 305 | memset (outbuf+1, 0, len - n); 306 | } 307 | /* Reverse the buffer */ 308 | for (i = 0; i < len/2; i++) 309 | { 310 | unsigned int tmp; 311 | 312 | tmp = outbuf[i+1]; 313 | outbuf[i+1] = outbuf[len-i]; 314 | outbuf[len-i] = tmp; 315 | } 316 | outbuf[0] = len; 317 | n = len + 1; 318 | } 319 | else 320 | { 321 | gcry_mpi_t Q; 322 | 323 | /* Note that "q" is computed by the get function and returned in 324 | * uncompressed form. */ 325 | Q = gcry_mpi_ec_get_mpi ("q", ecdh->ecctx, 0); 326 | if (!Q) 327 | { 328 | return gpg_error (GPG_ERR_INTERNAL); 329 | } 330 | debug_mpi (3, "ECDH Qour ", Q); 331 | 332 | /* Write as an ECPoint, that is prefix it with a one octet length. */ 333 | err = gcry_mpi_print (GCRYMPI_FMT_USG, outbuf+1, outbufsize-1, &n, Q); 334 | gcry_mpi_release (Q); 335 | if (err) 336 | return err; 337 | if (n > 255) 338 | return gpg_error (GPG_ERR_INV_DATA); 339 | outbuf[0] = n; 340 | n++; 341 | } 342 | 343 | *r_outbuflen = n; 344 | 345 | return 0; 346 | } 347 | 348 | 349 | /* Derive the shared secret Z and store it in OUTBUF. OUTBUFSIZE is 350 | * the available length of OUTBUF. On success the actual length of 351 | * OUTBUF is stored at R_OUTBUFLEN. */ 352 | gpg_error_t 353 | _ntbtls_ecdh_calc_secret (ecdh_context_t ecdh, 354 | unsigned char *outbuf, size_t outbufsize, 355 | size_t *r_outbuflen) 356 | { 357 | gpg_error_t err; 358 | gcry_mpi_point_t P = NULL; 359 | gcry_mpi_t d = NULL; 360 | gcry_mpi_t x = NULL; 361 | size_t n; 362 | 363 | if (!ecdh || !outbuf || !r_outbuflen) 364 | return gpg_error (GPG_ERR_INV_ARG); 365 | 366 | *r_outbuflen = 0; 367 | 368 | if (!ecdh->curve_name || !ecdh->ecctx || !ecdh->Qpeer) 369 | return gpg_error (GPG_ERR_NOT_INITIALIZED); 370 | 371 | /* 1. Check that Q_peer is on the curve 372 | * 2. Compute: P = d * Q_peer 373 | * 2. Check that P is not the point at infinity. 374 | * 3. Copy the x-coordinate of P to the output. 375 | */ 376 | 377 | if (!gcry_mpi_ec_curve_point (ecdh->Qpeer, ecdh->ecctx)) 378 | { 379 | err = gpg_error (GPG_ERR_INV_DATA); 380 | goto leave; 381 | } 382 | 383 | d = gcry_mpi_ec_get_mpi ("d", ecdh->ecctx, 0); 384 | if (!d) 385 | return gpg_error (GPG_ERR_NOT_INITIALIZED); 386 | 387 | P = gcry_mpi_point_new (0); 388 | gcry_mpi_ec_mul (P, d, ecdh->Qpeer, ecdh->ecctx); 389 | 390 | x = gcry_mpi_new (0); 391 | if (gcry_mpi_ec_get_affine (x, NULL, P, ecdh->ecctx)) 392 | { 393 | err = gpg_error (GPG_ERR_INV_DATA); 394 | goto leave; 395 | } 396 | 397 | err = gcry_mpi_print (GCRYMPI_FMT_USG, outbuf, outbufsize, &n, x); 398 | if (err) 399 | goto leave; 400 | 401 | if (ecdh->curve_name[0] == 'X') 402 | { 403 | gcry_mpi_t p; 404 | unsigned int pbits; 405 | int i; 406 | int len; 407 | 408 | p = gcry_mpi_ec_get_mpi ("p", ecdh->ecctx, 0); 409 | if (!p) 410 | { 411 | err = gpg_error (GPG_ERR_INTERNAL); 412 | goto leave; 413 | } 414 | pbits = gcry_mpi_get_nbits (p); 415 | len = (pbits+7)/8; 416 | gcry_mpi_release (p); 417 | if (len > 255) 418 | { 419 | err = gpg_error (GPG_ERR_INV_DATA); 420 | goto leave; 421 | } 422 | 423 | /* Fill zero, if shorter. */ 424 | if (n < len) 425 | { 426 | memmove (outbuf+len-n, outbuf, n); 427 | memset (outbuf, 0, len - n); 428 | } 429 | /* Reverse the buffer */ 430 | for (i = 0; i < len/2; i++) 431 | { 432 | unsigned int tmp; 433 | 434 | tmp = outbuf[i]; 435 | outbuf[i] = outbuf[len-i-1]; 436 | outbuf[len-i-1] = tmp; 437 | } 438 | n = len; 439 | } 440 | 441 | *r_outbuflen = n; 442 | 443 | leave: 444 | gcry_mpi_release (d); 445 | gcry_mpi_release (x); 446 | gcry_mpi_point_release (P); 447 | return err; 448 | } 449 | -------------------------------------------------------------------------------- /m4/ltoptions.m4: -------------------------------------------------------------------------------- 1 | # Helper functions for option handling. -*- Autoconf -*- 2 | # 3 | # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, 4 | # Inc. 5 | # Written by Gary V. Vaughan, 2004 6 | # 7 | # This file is free software; the Free Software Foundation gives 8 | # unlimited permission to copy and/or distribute it, with or without 9 | # modifications, as long as this notice is preserved. 10 | 11 | # serial 7 ltoptions.m4 12 | 13 | # This is to help aclocal find these macros, as it can't see m4_define. 14 | AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) 15 | 16 | 17 | # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) 18 | # ------------------------------------------ 19 | m4_define([_LT_MANGLE_OPTION], 20 | [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) 21 | 22 | 23 | # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) 24 | # --------------------------------------- 25 | # Set option OPTION-NAME for macro MACRO-NAME, and if there is a 26 | # matching handler defined, dispatch to it. Other OPTION-NAMEs are 27 | # saved as a flag. 28 | m4_define([_LT_SET_OPTION], 29 | [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl 30 | m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), 31 | _LT_MANGLE_DEFUN([$1], [$2]), 32 | [m4_warning([Unknown $1 option `$2'])])[]dnl 33 | ]) 34 | 35 | 36 | # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) 37 | # ------------------------------------------------------------ 38 | # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. 39 | m4_define([_LT_IF_OPTION], 40 | [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) 41 | 42 | 43 | # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) 44 | # ------------------------------------------------------- 45 | # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME 46 | # are set. 47 | m4_define([_LT_UNLESS_OPTIONS], 48 | [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), 49 | [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), 50 | [m4_define([$0_found])])])[]dnl 51 | m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 52 | ])[]dnl 53 | ]) 54 | 55 | 56 | # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) 57 | # ---------------------------------------- 58 | # OPTION-LIST is a space-separated list of Libtool options associated 59 | # with MACRO-NAME. If any OPTION has a matching handler declared with 60 | # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about 61 | # the unknown option and exit. 62 | m4_defun([_LT_SET_OPTIONS], 63 | [# Set options 64 | m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), 65 | [_LT_SET_OPTION([$1], _LT_Option)]) 66 | 67 | m4_if([$1],[LT_INIT],[ 68 | dnl 69 | dnl Simply set some default values (i.e off) if boolean options were not 70 | dnl specified: 71 | _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no 72 | ]) 73 | _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no 74 | ]) 75 | dnl 76 | dnl If no reference was made to various pairs of opposing options, then 77 | dnl we run the default mode handler for the pair. For example, if neither 78 | dnl `shared' nor `disable-shared' was passed, we enable building of shared 79 | dnl archives by default: 80 | _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) 81 | _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) 82 | _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) 83 | _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], 84 | [_LT_ENABLE_FAST_INSTALL]) 85 | ]) 86 | ])# _LT_SET_OPTIONS 87 | 88 | 89 | ## --------------------------------- ## 90 | ## Macros to handle LT_INIT options. ## 91 | ## --------------------------------- ## 92 | 93 | # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) 94 | # ----------------------------------------- 95 | m4_define([_LT_MANGLE_DEFUN], 96 | [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) 97 | 98 | 99 | # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) 100 | # ----------------------------------------------- 101 | m4_define([LT_OPTION_DEFINE], 102 | [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl 103 | ])# LT_OPTION_DEFINE 104 | 105 | 106 | # dlopen 107 | # ------ 108 | LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes 109 | ]) 110 | 111 | AU_DEFUN([AC_LIBTOOL_DLOPEN], 112 | [_LT_SET_OPTION([LT_INIT], [dlopen]) 113 | AC_DIAGNOSE([obsolete], 114 | [$0: Remove this warning and the call to _LT_SET_OPTION when you 115 | put the `dlopen' option into LT_INIT's first parameter.]) 116 | ]) 117 | 118 | dnl aclocal-1.4 backwards compatibility: 119 | dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) 120 | 121 | 122 | # win32-dll 123 | # --------- 124 | # Declare package support for building win32 dll's. 125 | LT_OPTION_DEFINE([LT_INIT], [win32-dll], 126 | [enable_win32_dll=yes 127 | 128 | case $host in 129 | *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) 130 | AC_CHECK_TOOL(AS, as, false) 131 | AC_CHECK_TOOL(DLLTOOL, dlltool, false) 132 | AC_CHECK_TOOL(OBJDUMP, objdump, false) 133 | ;; 134 | esac 135 | 136 | test -z "$AS" && AS=as 137 | _LT_DECL([], [AS], [1], [Assembler program])dnl 138 | 139 | test -z "$DLLTOOL" && DLLTOOL=dlltool 140 | _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl 141 | 142 | test -z "$OBJDUMP" && OBJDUMP=objdump 143 | _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl 144 | ])# win32-dll 145 | 146 | AU_DEFUN([AC_LIBTOOL_WIN32_DLL], 147 | [AC_REQUIRE([AC_CANONICAL_HOST])dnl 148 | _LT_SET_OPTION([LT_INIT], [win32-dll]) 149 | AC_DIAGNOSE([obsolete], 150 | [$0: Remove this warning and the call to _LT_SET_OPTION when you 151 | put the `win32-dll' option into LT_INIT's first parameter.]) 152 | ]) 153 | 154 | dnl aclocal-1.4 backwards compatibility: 155 | dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) 156 | 157 | 158 | # _LT_ENABLE_SHARED([DEFAULT]) 159 | # ---------------------------- 160 | # implement the --enable-shared flag, and supports the `shared' and 161 | # `disable-shared' LT_INIT options. 162 | # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. 163 | m4_define([_LT_ENABLE_SHARED], 164 | [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl 165 | AC_ARG_ENABLE([shared], 166 | [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], 167 | [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], 168 | [p=${PACKAGE-default} 169 | case $enableval in 170 | yes) enable_shared=yes ;; 171 | no) enable_shared=no ;; 172 | *) 173 | enable_shared=no 174 | # Look at the argument we got. We use all the common list separators. 175 | lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," 176 | for pkg in $enableval; do 177 | IFS="$lt_save_ifs" 178 | if test "X$pkg" = "X$p"; then 179 | enable_shared=yes 180 | fi 181 | done 182 | IFS="$lt_save_ifs" 183 | ;; 184 | esac], 185 | [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) 186 | 187 | _LT_DECL([build_libtool_libs], [enable_shared], [0], 188 | [Whether or not to build shared libraries]) 189 | ])# _LT_ENABLE_SHARED 190 | 191 | LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) 192 | LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) 193 | 194 | # Old names: 195 | AC_DEFUN([AC_ENABLE_SHARED], 196 | [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) 197 | ]) 198 | 199 | AC_DEFUN([AC_DISABLE_SHARED], 200 | [_LT_SET_OPTION([LT_INIT], [disable-shared]) 201 | ]) 202 | 203 | AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) 204 | AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) 205 | 206 | dnl aclocal-1.4 backwards compatibility: 207 | dnl AC_DEFUN([AM_ENABLE_SHARED], []) 208 | dnl AC_DEFUN([AM_DISABLE_SHARED], []) 209 | 210 | 211 | 212 | # _LT_ENABLE_STATIC([DEFAULT]) 213 | # ---------------------------- 214 | # implement the --enable-static flag, and support the `static' and 215 | # `disable-static' LT_INIT options. 216 | # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. 217 | m4_define([_LT_ENABLE_STATIC], 218 | [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl 219 | AC_ARG_ENABLE([static], 220 | [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], 221 | [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], 222 | [p=${PACKAGE-default} 223 | case $enableval in 224 | yes) enable_static=yes ;; 225 | no) enable_static=no ;; 226 | *) 227 | enable_static=no 228 | # Look at the argument we got. We use all the common list separators. 229 | lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," 230 | for pkg in $enableval; do 231 | IFS="$lt_save_ifs" 232 | if test "X$pkg" = "X$p"; then 233 | enable_static=yes 234 | fi 235 | done 236 | IFS="$lt_save_ifs" 237 | ;; 238 | esac], 239 | [enable_static=]_LT_ENABLE_STATIC_DEFAULT) 240 | 241 | _LT_DECL([build_old_libs], [enable_static], [0], 242 | [Whether or not to build static libraries]) 243 | ])# _LT_ENABLE_STATIC 244 | 245 | LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) 246 | LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) 247 | 248 | # Old names: 249 | AC_DEFUN([AC_ENABLE_STATIC], 250 | [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) 251 | ]) 252 | 253 | AC_DEFUN([AC_DISABLE_STATIC], 254 | [_LT_SET_OPTION([LT_INIT], [disable-static]) 255 | ]) 256 | 257 | AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) 258 | AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) 259 | 260 | dnl aclocal-1.4 backwards compatibility: 261 | dnl AC_DEFUN([AM_ENABLE_STATIC], []) 262 | dnl AC_DEFUN([AM_DISABLE_STATIC], []) 263 | 264 | 265 | 266 | # _LT_ENABLE_FAST_INSTALL([DEFAULT]) 267 | # ---------------------------------- 268 | # implement the --enable-fast-install flag, and support the `fast-install' 269 | # and `disable-fast-install' LT_INIT options. 270 | # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. 271 | m4_define([_LT_ENABLE_FAST_INSTALL], 272 | [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl 273 | AC_ARG_ENABLE([fast-install], 274 | [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], 275 | [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], 276 | [p=${PACKAGE-default} 277 | case $enableval in 278 | yes) enable_fast_install=yes ;; 279 | no) enable_fast_install=no ;; 280 | *) 281 | enable_fast_install=no 282 | # Look at the argument we got. We use all the common list separators. 283 | lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," 284 | for pkg in $enableval; do 285 | IFS="$lt_save_ifs" 286 | if test "X$pkg" = "X$p"; then 287 | enable_fast_install=yes 288 | fi 289 | done 290 | IFS="$lt_save_ifs" 291 | ;; 292 | esac], 293 | [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) 294 | 295 | _LT_DECL([fast_install], [enable_fast_install], [0], 296 | [Whether or not to optimize for fast installation])dnl 297 | ])# _LT_ENABLE_FAST_INSTALL 298 | 299 | LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) 300 | LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) 301 | 302 | # Old names: 303 | AU_DEFUN([AC_ENABLE_FAST_INSTALL], 304 | [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) 305 | AC_DIAGNOSE([obsolete], 306 | [$0: Remove this warning and the call to _LT_SET_OPTION when you put 307 | the `fast-install' option into LT_INIT's first parameter.]) 308 | ]) 309 | 310 | AU_DEFUN([AC_DISABLE_FAST_INSTALL], 311 | [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) 312 | AC_DIAGNOSE([obsolete], 313 | [$0: Remove this warning and the call to _LT_SET_OPTION when you put 314 | the `disable-fast-install' option into LT_INIT's first parameter.]) 315 | ]) 316 | 317 | dnl aclocal-1.4 backwards compatibility: 318 | dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) 319 | dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) 320 | 321 | 322 | # _LT_WITH_PIC([MODE]) 323 | # -------------------- 324 | # implement the --with-pic flag, and support the `pic-only' and `no-pic' 325 | # LT_INIT options. 326 | # MODE is either `yes' or `no'. If omitted, it defaults to `both'. 327 | m4_define([_LT_WITH_PIC], 328 | [AC_ARG_WITH([pic], 329 | [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], 330 | [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], 331 | [lt_p=${PACKAGE-default} 332 | case $withval in 333 | yes|no) pic_mode=$withval ;; 334 | *) 335 | pic_mode=default 336 | # Look at the argument we got. We use all the common list separators. 337 | lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," 338 | for lt_pkg in $withval; do 339 | IFS="$lt_save_ifs" 340 | if test "X$lt_pkg" = "X$lt_p"; then 341 | pic_mode=yes 342 | fi 343 | done 344 | IFS="$lt_save_ifs" 345 | ;; 346 | esac], 347 | [pic_mode=default]) 348 | 349 | test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) 350 | 351 | _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl 352 | ])# _LT_WITH_PIC 353 | 354 | LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) 355 | LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) 356 | 357 | # Old name: 358 | AU_DEFUN([AC_LIBTOOL_PICMODE], 359 | [_LT_SET_OPTION([LT_INIT], [pic-only]) 360 | AC_DIAGNOSE([obsolete], 361 | [$0: Remove this warning and the call to _LT_SET_OPTION when you 362 | put the `pic-only' option into LT_INIT's first parameter.]) 363 | ]) 364 | 365 | dnl aclocal-1.4 backwards compatibility: 366 | dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) 367 | 368 | ## ----------------- ## 369 | ## LTDL_INIT Options ## 370 | ## ----------------- ## 371 | 372 | m4_define([_LTDL_MODE], []) 373 | LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], 374 | [m4_define([_LTDL_MODE], [nonrecursive])]) 375 | LT_OPTION_DEFINE([LTDL_INIT], [recursive], 376 | [m4_define([_LTDL_MODE], [recursive])]) 377 | LT_OPTION_DEFINE([LTDL_INIT], [subproject], 378 | [m4_define([_LTDL_MODE], [subproject])]) 379 | 380 | m4_define([_LTDL_TYPE], []) 381 | LT_OPTION_DEFINE([LTDL_INIT], [installable], 382 | [m4_define([_LTDL_TYPE], [installable])]) 383 | LT_OPTION_DEFINE([LTDL_INIT], [convenience], 384 | [m4_define([_LTDL_TYPE], [convenience])]) 385 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # autogen.sh 3 | # Copyright (C) 2003, 2014, 2017, 2018 g10 Code GmbH 4 | # 5 | # This file is free software; as a special exception the author gives 6 | # unlimited permission to copy and/or distribute it, with or without 7 | # modifications, as long as this notice is preserved. 8 | # 9 | # This program is distributed in the hope that it will be useful, but 10 | # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 11 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | # 13 | # This is a generic script to create the configure script and handle cross 14 | # build environments. It requires the presence of a autogen.rc file to 15 | # configure it for the respective package. It is maintained as part of 16 | # GnuPG and source copied by other packages. 17 | # 18 | # Version: 2018-07-10 19 | 20 | configure_ac="configure.ac" 21 | 22 | cvtver () { 23 | awk 'NR==1 {split($NF,A,".");X=1000000*A[1]+1000*A[2]+A[3];print X;exit 0}' 24 | } 25 | 26 | check_version () { 27 | if [ $(( `("$1" --version || echo "0") | cvtver` >= $2 )) = 1 ]; then 28 | return 0 29 | fi 30 | echo "**Error**: "\`$1\'" not installed or too old." >&2 31 | echo ' Version '$3' or newer is required.' >&2 32 | [ -n "$4" ] && echo ' Note that this is part of '\`$4\''.' >&2 33 | DIE="yes" 34 | return 1 35 | } 36 | 37 | fatal () { 38 | echo "autogen.sh:" "$*" >&2 39 | DIE=yes 40 | } 41 | 42 | info () { 43 | if [ -z "${SILENT}" ]; then 44 | echo "autogen.sh:" "$*" >&2 45 | fi 46 | } 47 | 48 | die_p () { 49 | if [ "$DIE" = "yes" ]; then 50 | echo "autogen.sh: Stop." >&2 51 | exit 1 52 | fi 53 | } 54 | 55 | replace_sysroot () { 56 | configure_opts=$(echo $configure_opts | sed "s#@SYSROOT@#${w32root}#g") 57 | extraoptions=$(echo $extraoptions | sed "s#@SYSROOT@#${w32root}#g") 58 | } 59 | 60 | # Allow to override the default tool names 61 | AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX} 62 | AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX} 63 | 64 | AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX} 65 | ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX} 66 | 67 | GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX} 68 | MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX} 69 | 70 | DIE=no 71 | FORCE= 72 | SILENT= 73 | PRINT_HOST=no 74 | PRINT_BUILD=no 75 | tmp=$(dirname "$0") 76 | tsdir=$(cd "${tmp}"; pwd) 77 | 78 | if [ -n "${AUTOGEN_SH_SILENT}" ]; then 79 | SILENT=" --silent" 80 | fi 81 | if test x"$1" = x"--help"; then 82 | echo "usage: ./autogen.sh [OPTIONS] [ARGS]" 83 | echo " Options:" 84 | echo " --silent Silent operation" 85 | echo " --force Pass --force to autoconf" 86 | echo " --find-version Helper for configure.ac" 87 | echo " --git-build Run all commands to build from a Git" 88 | echo " --print-host Print only the host triplet" 89 | echo " --print-build Print only the build platform triplet" 90 | echo " --build-TYPE Configure to cross build for TYPE" 91 | echo "" 92 | echo " ARGS are passed to configure in --build-TYPE mode." 93 | echo " Configuration for this script is expected in autogen.rc" 94 | exit 0 95 | fi 96 | if test x"$1" = x"--silent"; then 97 | SILENT=" --silent" 98 | shift 99 | fi 100 | if test x"$1" = x"--force"; then 101 | FORCE=" --force" 102 | shift 103 | fi 104 | if test x"$1" = x"--print-host"; then 105 | PRINT_HOST=yes 106 | shift 107 | fi 108 | if test x"$1" = x"--print-build"; then 109 | PRINT_BUILD=yes 110 | shift 111 | fi 112 | 113 | 114 | # Reject unsafe characters in $HOME, $tsdir and cwd. We consider spaces 115 | # as unsafe because it is too easy to get scripts wrong in this regard. 116 | am_lf=' 117 | ' 118 | case `pwd` in 119 | *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*) 120 | fatal "unsafe working directory name" ;; 121 | esac 122 | case $tsdir in 123 | *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*) 124 | fatal "unsafe source directory: \`$tsdir'" ;; 125 | esac 126 | case $HOME in 127 | *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*) 128 | fatal "unsafe home directory: \`$HOME'" ;; 129 | esac 130 | die_p 131 | 132 | 133 | # List of variables sourced from autogen.rc. The strings '@SYSROOT@' in 134 | # these variables are replaced by the actual system root. 135 | configure_opts= 136 | extraoptions= 137 | # List of optional variables sourced from autogen.rc and ~/.gnupg-autogen.rc 138 | w32_toolprefixes= 139 | w32_extraoptions= 140 | w32ce_toolprefixes= 141 | w32ce_extraoptions= 142 | w64_toolprefixes= 143 | w64_extraoptions= 144 | amd64_toolprefixes= 145 | # End list of optional variables sourced from ~/.gnupg-autogen.rc 146 | # What follows are variables which are sourced but default to 147 | # environment variables or lacking them hardcoded values. 148 | #w32root= 149 | #w32ce_root= 150 | #w64root= 151 | #amd64root= 152 | 153 | # Convenience option to use certain configure options for some hosts. 154 | myhost="" 155 | myhostsub="" 156 | case "$1" in 157 | --find-version) 158 | myhost="find-version" 159 | SILENT=" --silent" 160 | shift 161 | ;; 162 | --git-build) 163 | myhost="git-build" 164 | shift 165 | ;; 166 | --build-w32) 167 | myhost="w32" 168 | shift 169 | ;; 170 | --build-w32ce) 171 | myhost="w32" 172 | myhostsub="ce" 173 | shift 174 | ;; 175 | --build-w64) 176 | myhost="w32" 177 | myhostsub="64" 178 | shift 179 | ;; 180 | --build-amd64) 181 | myhost="amd64" 182 | shift 183 | ;; 184 | --build*) 185 | fatal "**Error**: invalid build option $1" 186 | shift 187 | ;; 188 | *) 189 | ;; 190 | esac 191 | die_p 192 | 193 | 194 | # **** GIT BUILD **** 195 | # This is a helper to build from git. 196 | if [ "$myhost" = "git-build" ]; then 197 | tmp="$(pwd)" 198 | cd "$tsdir" || fatal "error cd-ing to $tsdir" 199 | ./autogen.sh || fatal "error running ./autogen.sh" 200 | cd "$tmp" || fatal "error cd-ing back to $tmp" 201 | die_p 202 | "$tsdir"/configure || fatal "error running $tsdir/configure" 203 | die_p 204 | make || fatal "error running make" 205 | die_p 206 | make check || fatal "error running male check" 207 | die_p 208 | exit 0 209 | fi 210 | # **** end GIT BUILD **** 211 | 212 | 213 | # Source our configuration 214 | if [ -f "${tsdir}/autogen.rc" ]; then 215 | . "${tsdir}/autogen.rc" 216 | fi 217 | 218 | # Source optional site specific configuration 219 | if [ -f "$HOME/.gnupg-autogen.rc" ]; then 220 | info "sourcing extra definitions from $HOME/.gnupg-autogen.rc" 221 | . "$HOME/.gnupg-autogen.rc" 222 | fi 223 | 224 | 225 | # **** FIND VERSION **** 226 | # This is a helper for the configure.ac M4 magic 227 | # Called 228 | # ./autogen.sh --find-version PACKAGE MAJOR MINOR [MICRO] 229 | # returns a complete version string with automatic beta numbering. 230 | if [ "$myhost" = "find-version" ]; then 231 | package="$1" 232 | major="$2" 233 | minor="$3" 234 | micro="$4" 235 | 236 | if [ -z "$package" -o -z "$major" -o -z "$minor" ]; then 237 | echo "usage: ./autogen.sh --find-version PACKAGE MAJOR MINOR [MICRO]" >&2 238 | exit 1 239 | fi 240 | 241 | if [ -z "$micro" ]; then 242 | matchstr1="$package-$major.[0-9]*" 243 | matchstr2="$package-$major-base" 244 | vers="$major.$minor" 245 | else 246 | matchstr1="$package-$major.$minor.[0-9]*" 247 | matchstr2="$package-$major.$minor-base" 248 | vers="$major.$minor.$micro" 249 | fi 250 | 251 | beta=no 252 | if [ -e .git ]; then 253 | ingit=yes 254 | tmp=$(git describe --match "${matchstr1}" --long 2>/dev/null) 255 | tmp=$(echo "$tmp" | sed s/^"$package"//) 256 | if [ -n "$tmp" ]; then 257 | tmp=$(echo "$tmp" | sed s/^"$package"// \ 258 | | awk -F- '$3!=0 && $3 !~ /^beta/ {print"-beta"$3}') 259 | else 260 | tmp=$(git describe --match "${matchstr2}" --long 2>/dev/null \ 261 | | awk -F- '$4!=0{print"-beta"$4}') 262 | fi 263 | [ -n "$tmp" ] && beta=yes 264 | rev=$(git rev-parse --short HEAD | tr -d '\n\r') 265 | rvd=$((0x$(echo ${rev} | dd bs=1 count=4 2>/dev/null))) 266 | else 267 | ingit=no 268 | beta=yes 269 | tmp="-unknown" 270 | rev="0000000" 271 | rvd="0" 272 | fi 273 | 274 | echo "$package-$vers$tmp:$beta:$ingit:$vers$tmp:$vers:$tmp:$rev:$rvd:" 275 | exit 0 276 | fi 277 | # **** end FIND VERSION **** 278 | 279 | 280 | if [ ! -f "$tsdir/build-aux/config.guess" ]; then 281 | fatal "$tsdir/build-aux/config.guess not found" 282 | exit 1 283 | fi 284 | build=`$tsdir/build-aux/config.guess` 285 | if [ $PRINT_BUILD = yes ]; then 286 | echo "$build" 287 | exit 0 288 | fi 289 | 290 | 291 | 292 | # ****************** 293 | # W32 build script 294 | # ****************** 295 | if [ "$myhost" = "w32" ]; then 296 | case $myhostsub in 297 | ce) 298 | w32root="$w32ce_root" 299 | [ -z "$w32root" ] && w32root="$HOME/w32ce_root" 300 | toolprefixes="$w32ce_toolprefixes arm-mingw32ce" 301 | extraoptions="$extraoptions $w32ce_extraoptions" 302 | ;; 303 | 64) 304 | w32root="$w64root" 305 | [ -z "$w32root" ] && w32root="$HOME/w64root" 306 | toolprefixes="$w64_toolprefixes x86_64-w64-mingw32" 307 | extraoptions="$extraoptions $w64_extraoptions" 308 | ;; 309 | *) 310 | [ -z "$w32root" ] && w32root="$HOME/w32root" 311 | toolprefixes="$w32_toolprefixes i686-w64-mingw32 i586-mingw32msvc" 312 | toolprefixes="$toolprefixes i386-mingw32msvc mingw32" 313 | extraoptions="$extraoptions $w32_extraoptions" 314 | ;; 315 | esac 316 | info "Using $w32root as standard install directory" 317 | replace_sysroot 318 | 319 | # Locate the cross compiler 320 | crossbindir= 321 | for host in $toolprefixes; do 322 | if ${host}-gcc --version >/dev/null 2>&1 ; then 323 | crossbindir=/usr/${host}/bin 324 | conf_CC="CC=${host}-gcc" 325 | break; 326 | fi 327 | done 328 | if [ -z "$crossbindir" ]; then 329 | fatal "cross compiler kit not installed" 330 | if [ -z "$myhostsub" ]; then 331 | info "Under Debian GNU/Linux, you may install it using" 332 | info " apt-get install mingw32 mingw32-runtime mingw32-binutils" 333 | fi 334 | die_p 335 | fi 336 | if [ $PRINT_HOST = yes ]; then 337 | echo "$host" 338 | exit 0 339 | fi 340 | 341 | if [ -f "$tsdir/config.log" ]; then 342 | if ! head $tsdir/config.log | grep "$host" >/dev/null; then 343 | fatal "Please run a 'make distclean' first" 344 | die_p 345 | fi 346 | fi 347 | 348 | $tsdir/configure --enable-maintainer-mode ${SILENT} \ 349 | --prefix=${w32root} \ 350 | --host=${host} --build=${build} SYSROOT=${w32root} \ 351 | PKG_CONFIG_LIBDIR=${w32root}/lib/pkgconfig \ 352 | ${configure_opts} ${extraoptions} "$@" 353 | rc=$? 354 | exit $rc 355 | fi 356 | # ***** end W32 build script ******* 357 | 358 | # ***** AMD64 cross build script ******* 359 | # Used to cross-compile for AMD64 (for testing) 360 | if [ "$myhost" = "amd64" ]; then 361 | [ -z "$amd64root" ] && amd64root="$HOME/amd64root" 362 | info "Using $amd64root as standard install directory" 363 | replace_sysroot 364 | 365 | toolprefixes="$amd64_toolprefixes x86_64-linux-gnu amd64-linux-gnu" 366 | 367 | # Locate the cross compiler 368 | crossbindir= 369 | for host in $toolprefixes ; do 370 | if ${host}-gcc --version >/dev/null 2>&1 ; then 371 | crossbindir=/usr/${host}/bin 372 | conf_CC="CC=${host}-gcc" 373 | break; 374 | fi 375 | done 376 | if [ -z "$crossbindir" ]; then 377 | echo "Cross compiler kit not installed" >&2 378 | echo "Stop." >&2 379 | exit 1 380 | fi 381 | if [ $PRINT_HOST = yes ]; then 382 | echo "$host" 383 | exit 0 384 | fi 385 | 386 | if [ -f "$tsdir/config.log" ]; then 387 | if ! head $tsdir/config.log | grep "$host" >/dev/null; then 388 | echo "Please run a 'make distclean' first" >&2 389 | exit 1 390 | fi 391 | fi 392 | 393 | $tsdir/configure --enable-maintainer-mode ${SILENT} \ 394 | --prefix=${amd64root} \ 395 | --host=${host} --build=${build} \ 396 | ${configure_opts} ${extraoptions} "$@" 397 | rc=$? 398 | exit $rc 399 | fi 400 | # ***** end AMD64 cross build script ******* 401 | 402 | 403 | # Grep the required versions from configure.ac 404 | autoconf_vers=`sed -n '/^AC_PREREQ(/ { 405 | s/^.*(\(.*\))/\1/p 406 | q 407 | }' ${configure_ac}` 408 | autoconf_vers_num=`echo "$autoconf_vers" | cvtver` 409 | 410 | automake_vers=`sed -n '/^min_automake_version=/ { 411 | s/^.*="\(.*\)"/\1/p 412 | q 413 | }' ${configure_ac}` 414 | automake_vers_num=`echo "$automake_vers" | cvtver` 415 | 416 | if [ -d "${tsdir}/po" ]; then 417 | gettext_vers=`sed -n '/^AM_GNU_GETTEXT_VERSION(/ { 418 | s/^.*\[\(.*\)])/\1/p 419 | q 420 | }' ${configure_ac}` 421 | gettext_vers_num=`echo "$gettext_vers" | cvtver` 422 | else 423 | gettext_vers="n/a" 424 | fi 425 | 426 | if [ -z "$autoconf_vers" -o -z "$automake_vers" -o -z "$gettext_vers" ] 427 | then 428 | echo "**Error**: version information not found in "\`${configure_ac}\'"." >&2 429 | exit 1 430 | fi 431 | 432 | 433 | if check_version $AUTOCONF $autoconf_vers_num $autoconf_vers ; then 434 | check_version $AUTOHEADER $autoconf_vers_num $autoconf_vers autoconf 435 | fi 436 | if check_version $AUTOMAKE $automake_vers_num $automake_vers; then 437 | check_version $ACLOCAL $automake_vers_num $autoconf_vers automake 438 | fi 439 | if [ "$gettext_vers" != "n/a" ]; then 440 | if check_version $GETTEXT $gettext_vers_num $gettext_vers; then 441 | check_version $MSGMERGE $gettext_vers_num $gettext_vers gettext 442 | fi 443 | fi 444 | 445 | if [ "$DIE" = "yes" ]; then 446 | cat </dev/null 2>/dev/null; then 460 | [ -z "${SILENT}" ] && CP="$CP -v" 461 | fi 462 | if [ -f .git/hooks/pre-commit.sample -a ! -f .git/hooks/pre-commit ] ; then 463 | [ -z "${SILENT}" ] && cat <' header file. The option `-nodtk' can be used as 236 | a workaround. If GNU CC is not installed, it is therefore recommended 237 | to try 238 | 239 | ./configure CC="cc" 240 | 241 | and if that doesn't work, try 242 | 243 | ./configure CC="cc -nodtk" 244 | 245 | On Solaris, don't put `/usr/ucb' early in your `PATH'. This 246 | directory contains several dysfunctional programs; working variants of 247 | these programs are available in `/usr/bin'. So, if you need `/usr/ucb' 248 | in your `PATH', put it _after_ `/usr/bin'. 249 | 250 | On Haiku, software installed for all users goes in `/boot/common', 251 | not `/usr/local'. It is recommended to use the following options: 252 | 253 | ./configure --prefix=/boot/common 254 | 255 | Specifying the System Type 256 | ========================== 257 | 258 | There may be some features `configure' cannot figure out 259 | automatically, but needs to determine by the type of machine the package 260 | will run on. Usually, assuming the package is built to be run on the 261 | _same_ architectures, `configure' can figure that out, but if it prints 262 | a message saying it cannot guess the machine type, give it the 263 | `--build=TYPE' option. TYPE can either be a short name for the system 264 | type, such as `sun4', or a canonical name which has the form: 265 | 266 | CPU-COMPANY-SYSTEM 267 | 268 | where SYSTEM can have one of these forms: 269 | 270 | OS 271 | KERNEL-OS 272 | 273 | See the file `config.sub' for the possible values of each field. If 274 | `config.sub' isn't included in this package, then this package doesn't 275 | need to know the machine type. 276 | 277 | If you are _building_ compiler tools for cross-compiling, you should 278 | use the option `--target=TYPE' to select the type of system they will 279 | produce code for. 280 | 281 | If you want to _use_ a cross compiler, that generates code for a 282 | platform different from the build platform, you should specify the 283 | "host" platform (i.e., that on which the generated programs will 284 | eventually be run) with `--host=TYPE'. 285 | 286 | Sharing Defaults 287 | ================ 288 | 289 | If you want to set default values for `configure' scripts to share, 290 | you can create a site shell script called `config.site' that gives 291 | default values for variables like `CC', `cache_file', and `prefix'. 292 | `configure' looks for `PREFIX/share/config.site' if it exists, then 293 | `PREFIX/etc/config.site' if it exists. Or, you can set the 294 | `CONFIG_SITE' environment variable to the location of the site script. 295 | A warning: not all `configure' scripts look for a site script. 296 | 297 | Defining Variables 298 | ================== 299 | 300 | Variables not defined in a site shell script can be set in the 301 | environment passed to `configure'. However, some packages may run 302 | configure again during the build, and the customized values of these 303 | variables may be lost. In order to avoid this problem, you should set 304 | them in the `configure' command line, using `VAR=value'. For example: 305 | 306 | ./configure CC=/usr/local2/bin/gcc 307 | 308 | causes the specified `gcc' to be used as the C compiler (unless it is 309 | overridden in the site shell script). 310 | 311 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 312 | an Autoconf bug. Until the bug is fixed you can use this workaround: 313 | 314 | CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash 315 | 316 | `configure' Invocation 317 | ====================== 318 | 319 | `configure' recognizes the following options to control how it 320 | operates. 321 | 322 | `--help' 323 | `-h' 324 | Print a summary of all of the options to `configure', and exit. 325 | 326 | `--help=short' 327 | `--help=recursive' 328 | Print a summary of the options unique to this package's 329 | `configure', and exit. The `short' variant lists options used 330 | only in the top level, while the `recursive' variant lists options 331 | also present in any nested packages. 332 | 333 | `--version' 334 | `-V' 335 | Print the version of Autoconf used to generate the `configure' 336 | script, and exit. 337 | 338 | `--cache-file=FILE' 339 | Enable the cache: use and save the results of the tests in FILE, 340 | traditionally `config.cache'. FILE defaults to `/dev/null' to 341 | disable caching. 342 | 343 | `--config-cache' 344 | `-C' 345 | Alias for `--cache-file=config.cache'. 346 | 347 | `--quiet' 348 | `--silent' 349 | `-q' 350 | Do not print messages saying which checks are being made. To 351 | suppress all normal output, redirect it to `/dev/null' (any error 352 | messages will still be shown). 353 | 354 | `--srcdir=DIR' 355 | Look for the package's source code in directory DIR. Usually 356 | `configure' can determine that directory automatically. 357 | 358 | `--prefix=DIR' 359 | Use DIR as the installation prefix. *note Installation Names:: 360 | for more details, including other options available for fine-tuning 361 | the installation locations. 362 | 363 | `--no-create' 364 | `-n' 365 | Run the configure checks, but stop before creating any output 366 | files. 367 | 368 | `configure' also accepts some other, not widely useful, options. Run 369 | `configure --help' for more details. 370 | --------------------------------------------------------------------------------