|
Packit |
549fdc |
\input texinfo @c -*-texinfo-*-
|
|
Packit |
549fdc |
@comment %**start of header
|
|
Packit |
549fdc |
@setfilename gnutls-guile.info
|
|
Packit |
549fdc |
@include version-guile.texi
|
|
Packit |
549fdc |
@settitle GnuTLS-Guile @value{VERSION}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@c don't indent the paragraphs.
|
|
Packit |
549fdc |
@paragraphindent 0
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@c Unify some of the indices.
|
|
Packit |
549fdc |
@syncodeindex tp fn
|
|
Packit |
549fdc |
@syncodeindex pg cp
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@comment %**end of header
|
|
Packit |
549fdc |
@finalout
|
|
Packit |
549fdc |
@copying
|
|
Packit |
549fdc |
This manual is last updated @value{UPDATED} for version
|
|
Packit |
549fdc |
@value{VERSION} of GnuTLS.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
Copyright @copyright{} 2001-2012, 2014, 2016 Free Software Foundation, Inc.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@quotation
|
|
Packit |
549fdc |
Permission is granted to copy, distribute and/or modify this document
|
|
Packit |
549fdc |
under the terms of the GNU Free Documentation License, Version 1.3 or
|
|
Packit |
549fdc |
any later version published by the Free Software Foundation; with no
|
|
Packit |
549fdc |
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
|
|
Packit |
549fdc |
copy of the license is included in the section entitled ``GNU Free
|
|
Packit |
549fdc |
Documentation License''.
|
|
Packit |
549fdc |
@end quotation
|
|
Packit |
549fdc |
@end copying
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@dircategory Software libraries
|
|
Packit |
549fdc |
@direntry
|
|
Packit |
549fdc |
* GnuTLS-Guile: (gnutls-guile). GNU Transport Layer Security Library. Guile bindings.
|
|
Packit |
549fdc |
@end direntry
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@titlepage
|
|
Packit |
549fdc |
@title GnuTLS-Guile
|
|
Packit |
549fdc |
@subtitle Guile binding for GNU TLS
|
|
Packit |
549fdc |
@subtitle for version @value{VERSION}, @value{UPDATED}
|
|
Packit |
549fdc |
@sp 7
|
|
Packit |
549fdc |
@image{gnutls-logo,6cm,6cm}
|
|
Packit |
549fdc |
@page
|
|
Packit |
549fdc |
@vskip 0pt plus 1filll
|
|
Packit |
549fdc |
@insertcopying
|
|
Packit |
549fdc |
@end titlepage
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@macro xcite{ref}
|
|
Packit |
549fdc |
[\ref\] (@pxref{Bibliography})
|
|
Packit |
549fdc |
@end macro
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@contents
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@node Top
|
|
Packit |
549fdc |
@top GnuTLS-Guile
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@insertcopying
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@menu
|
|
Packit |
549fdc |
* Preface:: Preface.
|
|
Packit |
549fdc |
* Guile Preparations:: Note on installation and environment.
|
|
Packit |
549fdc |
* Guile API Conventions:: Naming conventions and other idiosyncrasies.
|
|
Packit |
549fdc |
* Guile Examples:: Quick start.
|
|
Packit |
549fdc |
* Guile Reference:: The Scheme GnuTLS programming interface.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
* Copying Information:: You can copy and modify this manual.
|
|
Packit |
549fdc |
* Procedure Index::
|
|
Packit |
549fdc |
* Concept Index::
|
|
Packit |
549fdc |
@end menu
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@node Preface
|
|
Packit |
549fdc |
@chapter Preface
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
This manual describes the @uref{http://www.gnu.org/software/guile/,
|
|
Packit |
549fdc |
GNU Guile} Scheme programming interface to GnuTLS, which is distributed
|
|
Packit |
549fdc |
as part of @uref{http://gnutls.org,GnuTLS}. The reader is
|
|
Packit |
549fdc |
assumed to have basic knowledge of the protocol and library. Details
|
|
Packit |
549fdc |
missing from this chapter may be found in Function reference,
|
|
Packit |
549fdc |
of the C API reference.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
At this stage, not all the C functions are available from Scheme, but
|
|
Packit |
549fdc |
a large subset thereof is available.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@c *********************************************************************
|
|
Packit |
549fdc |
@node Guile Preparations
|
|
Packit |
549fdc |
@chapter Guile Preparations
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
The GnuTLS Guile bindings are available for Guile's 2.0 stable series,
|
|
Packit |
549fdc |
as well as the forthcoming 2.2 series and the legacy 1.8 series.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
By default they are installed under the GnuTLS installation directory,
|
|
Packit |
549fdc |
typically @file{/usr/local/share/guile/site/}). Normally Guile
|
|
Packit |
549fdc |
will not find the module there without help. You may experience
|
|
Packit |
549fdc |
something like this:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
$ guile
|
|
Packit |
549fdc |
@dots{}
|
|
Packit |
549fdc |
scheme@@(guile-user)> (use-modules (gnutls))
|
|
Packit |
549fdc |
ERROR: no code for module (gnutls)
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
There are two ways to solve this. The first is to make sure that when
|
|
Packit |
549fdc |
building GnuTLS, the Guile bindings will be installed in the same
|
|
Packit |
549fdc |
place where Guile looks. You may do this by using the
|
|
Packit |
549fdc |
@code{--with-guile-site-dir} parameter as follows:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
$ ./configure --with-guile-site-dir=no
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
This will instruct GnuTLS to attempt to install the Guile bindings
|
|
Packit |
549fdc |
where Guile will look for them. It will use @code{guile-config info
|
|
Packit |
549fdc |
pkgdatadir} to learn the path to use.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
If Guile was installed into @code{/usr}, you may also install GnuTLS
|
|
Packit |
549fdc |
using the same prefix:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
$ ./configure --prefix=/usr
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
If you want to specify the path to install the Guile bindings you can
|
|
Packit |
549fdc |
also specify the path directly:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
$ ./configure --with-guile-site-dir=/opt/guile/share/guile/site
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
The second solution requires some more work but may be easier to use
|
|
Packit |
549fdc |
if you do not have system administrator rights to your machine. You
|
|
Packit |
549fdc |
need to instruct Guile so that it finds the GnuTLS Guile bindings.
|
|
Packit |
549fdc |
Either use the @code{GUILE_LOAD_PATH} environment variable as follows:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
$ GUILE_LOAD_PATH="/usr/local/share/guile/site:$GUILE_LOAD_PATH" guile
|
|
Packit |
549fdc |
scheme@@(guile-user)> (use-modules (gnutls))
|
|
Packit |
549fdc |
scheme@@(guile-user)>
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
Alternatively, you can modify Guile's @code{%load-path} variable
|
|
Packit |
549fdc |
(@pxref{Build Config, Guile's run-time options,, guile, The GNU Guile
|
|
Packit |
549fdc |
Reference Manual}).
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
At this point, you might get an error regarding
|
|
Packit |
549fdc |
@file{guile-gnutls-v-2} similar to:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
gnutls.scm:361:1: In procedure dynamic-link in expression (load-extension "guile-gnutls-v-2" "scm_init_gnutls"):
|
|
Packit |
549fdc |
gnutls.scm:361:1: file: "guile-gnutls-v-2", message: "guile-gnutls-v-2.so: cannot open shared object file: No such file or directory"
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
In this case, you will need to modify the run-time linker path, for
|
|
Packit |
549fdc |
example as follows:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
$ LD_LIBRARY_PATH=/usr/local/lib GUILE_LOAD_PATH=/usr/local/share/guile/site guile
|
|
Packit |
549fdc |
scheme@@(guile-user)> (use-modules (gnutls))
|
|
Packit |
549fdc |
scheme@@(guile-user)>
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
To check that you got the intended GnuTLS library version, you may
|
|
Packit |
549fdc |
print the version number of the loaded library as follows:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
$ guile
|
|
Packit |
549fdc |
scheme@@(guile-user)> (use-modules (gnutls))
|
|
Packit |
549fdc |
scheme@@(guile-user)> (gnutls-version)
|
|
Packit |
549fdc |
"@value{VERSION}"
|
|
Packit |
549fdc |
scheme@@(guile-user)>
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@c *********************************************************************
|
|
Packit |
549fdc |
@node Guile API Conventions
|
|
Packit |
549fdc |
@chapter Guile API Conventions
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
This chapter details the conventions used by Guile API, as well as
|
|
Packit |
549fdc |
specificities of the mapping of the C API to Scheme.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@menu
|
|
Packit |
549fdc |
* Enumerates and Constants:: Representation of C-side constants.
|
|
Packit |
549fdc |
* Procedure Names:: Naming conventions.
|
|
Packit |
549fdc |
* Representation of Binary Data:: Binary data buffers.
|
|
Packit |
549fdc |
* Input and Output:: Input and output.
|
|
Packit |
549fdc |
* Exception Handling:: Exceptions.
|
|
Packit |
549fdc |
@end menu
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@node Enumerates and Constants
|
|
Packit |
549fdc |
@section Enumerates and Constants
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@cindex enumerate
|
|
Packit |
549fdc |
@cindex constant
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
Lots of enumerates and constants are used in the GnuTLS C API. For
|
|
Packit |
549fdc |
each C enumerate type, a disjoint Scheme type is used---thus,
|
|
Packit |
549fdc |
enumerate values and constants are not represented by Scheme symbols
|
|
Packit |
549fdc |
nor by integers. This makes it impossible to use an enumerate value
|
|
Packit |
549fdc |
of the wrong type on the Scheme side: such errors are automatically
|
|
Packit |
549fdc |
detected by type-checking.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
The enumerate values are bound to variables exported by the
|
|
Packit |
549fdc |
@code{(gnutls)} module. These variables
|
|
Packit |
549fdc |
are named according to the following convention:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@itemize
|
|
Packit |
549fdc |
@item All variable names are lower-case; the underscore @code{_}
|
|
Packit |
549fdc |
character used in the C API is replaced by hyphen @code{-}.
|
|
Packit |
549fdc |
@item All variable names are prepended by the name of the enumerate
|
|
Packit |
549fdc |
type and the slash @code{/} character.
|
|
Packit |
549fdc |
@item In some cases, the variable name is made more explicit than the
|
|
Packit |
549fdc |
one of the C API, e.g., by avoid abbreviations.
|
|
Packit |
549fdc |
@end itemize
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
Consider for instance this C-side enumerate:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
typedef enum
|
|
Packit |
549fdc |
@{
|
|
Packit |
549fdc |
GNUTLS_CRD_CERTIFICATE = 1,
|
|
Packit |
549fdc |
GNUTLS_CRD_ANON,
|
|
Packit |
549fdc |
GNUTLS_CRD_SRP,
|
|
Packit |
549fdc |
GNUTLS_CRD_PSK
|
|
Packit |
549fdc |
@} gnutls_credentials_type_t;
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
The corresponding Scheme values are bound to the following variables
|
|
Packit |
549fdc |
exported by the @code{(gnutls)} module:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
credentials/certificate
|
|
Packit |
549fdc |
credentials/anonymous
|
|
Packit |
549fdc |
credentials/srp
|
|
Packit |
549fdc |
credentials/psk
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
Hopefully, most variable names can be deduced from this convention.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
Scheme-side ``enumerate'' values can be compared using @code{eq?}
|
|
Packit |
549fdc |
(@pxref{Equality, equality predicates,, guile, The GNU Guile Reference
|
|
Packit |
549fdc |
Manual}). Consider the following example:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@findex session-cipher
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
(let ((session (make-session connection-end/client)))
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;;
|
|
Packit |
549fdc |
;; ...
|
|
Packit |
549fdc |
;;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Check the ciphering algorithm currently used by SESSION.
|
|
Packit |
549fdc |
(if (eq? cipher/arcfour (session-cipher session))
|
|
Packit |
549fdc |
(format #t "We're using the ARCFOUR algorithm")))
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
In addition, all enumerate values can be converted to a human-readable
|
|
Packit |
549fdc |
string, in a type-specific way. For instance, @code{(cipher->string
|
|
Packit |
549fdc |
cipher/arcfour)} yields @code{"ARCFOUR 128"}, while
|
|
Packit |
549fdc |
@code{(key-usage->string key-usage/digital-signature)} yields
|
|
Packit |
549fdc |
@code{"digital-signature"}. Note that these strings may not be
|
|
Packit |
549fdc |
sufficient for use in a user interface since they are fairly concise
|
|
Packit |
549fdc |
and not internationalized.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@node Procedure Names
|
|
Packit |
549fdc |
@section Procedure Names
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
Unlike C functions in GnuTLS, the corresponding Scheme procedures are
|
|
Packit |
549fdc |
named in a way that is close to natural English. Abbreviations are
|
|
Packit |
549fdc |
also avoided. For instance, the Scheme procedure corresponding to
|
|
Packit |
549fdc |
@code{gnutls_certificate_set_dh_params} is named
|
|
Packit |
549fdc |
@code{set-certificate-credentials-dh-parameters!}. The @code{gnutls_}
|
|
Packit |
549fdc |
prefix is always omitted from variable names since a similar effect
|
|
Packit |
549fdc |
can be achieved using Guile's nifty binding renaming facilities,
|
|
Packit |
549fdc |
should it be needed (@pxref{Using Guile Modules,,, guile, The GNU
|
|
Packit |
549fdc |
Guile Reference Manual}).
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
Often Scheme procedure names differ from C function names in a way
|
|
Packit |
549fdc |
that makes it clearer what objects they operate on. For example, the
|
|
Packit |
549fdc |
Scheme procedure named @code{set-session-transport-port!} corresponds
|
|
Packit |
549fdc |
to @code{gnutls_transport_set_ptr}, making it clear that this
|
|
Packit |
549fdc |
procedure applies to session.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@node Representation of Binary Data
|
|
Packit |
549fdc |
@section Representation of Binary Data
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
Many procedures operate on binary data. For instance,
|
|
Packit |
549fdc |
@code{pkcs3-import-dh-parameters} expects binary data as input.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@cindex bytevectors
|
|
Packit |
549fdc |
@cindex SRFI-4
|
|
Packit |
549fdc |
@cindex homogeneous vector
|
|
Packit |
549fdc |
Binary data is represented on the Scheme side using bytevectors
|
|
Packit |
549fdc |
(@pxref{Bytevectors,,, guile, The GNU Guile Reference Manual}).
|
|
Packit |
549fdc |
Homogeneous vectors such as SRFI-4 @code{u8vector}s can also be
|
|
Packit |
549fdc |
used@footnote{Historically, SRFI-4 @code{u8vector}s are the closest
|
|
Packit |
549fdc |
thing to bytevectors that Guile 1.8 and earlier supported.}.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
As an example, generating and then exporting Diffie-Hellman parameters
|
|
Packit |
549fdc |
in the PEM format can be done as follows:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@findex make-dh-parameters
|
|
Packit |
549fdc |
@findex pkcs3-export-dh-parameters
|
|
Packit |
549fdc |
@vindex x509-certificate-format/pem
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
(let* ((dh (make-dh-parameters 1024))
|
|
Packit |
549fdc |
(pem (pkcs3-export-dh-parameters dh
|
|
Packit |
549fdc |
x509-certificate-format/pem)))
|
|
Packit |
549fdc |
(call-with-output-file "some-file.pem"
|
|
Packit |
549fdc |
(lambda (port)
|
|
Packit |
549fdc |
(uniform-vector-write pem port))))
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@node Input and Output
|
|
Packit |
549fdc |
@section Input and Output
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@findex set-session-transport-port!
|
|
Packit |
549fdc |
@findex set-session-transport-fd!
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
The underlying transport of a TLS session can be any Scheme
|
|
Packit |
549fdc |
input/output port (@pxref{Ports and File Descriptors,,, guile, The GNU
|
|
Packit |
549fdc |
Guile Reference Manual}). This has to be specified using
|
|
Packit |
549fdc |
@code{set-session-transport-port!}.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
However, for better performance, a raw file descriptor can be
|
|
Packit |
549fdc |
specified, using @code{set-session-transport-fd!}. For instance, if
|
|
Packit |
549fdc |
the transport layer is a socket port over an OS-provided socket, you
|
|
Packit |
549fdc |
can use the @code{port->fdes} or @code{fileno} procedure to obtain the
|
|
Packit |
549fdc |
underlying file descriptor and pass it to
|
|
Packit |
549fdc |
@code{set-session-transport-fd!} (@pxref{Ports and File Descriptors,
|
|
Packit |
549fdc |
@code{port->fdes} and @code{fileno},, guile, The GNU Guile Reference
|
|
Packit |
549fdc |
Manual}). This would work as follows:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
(let ((socket (socket PF_INET SOCK_STREAM 0))
|
|
Packit |
549fdc |
(session (make-session connection-end/client)))
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;;
|
|
Packit |
549fdc |
;; Establish a TCP connection...
|
|
Packit |
549fdc |
;;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Use the file descriptor that underlies SOCKET.
|
|
Packit |
549fdc |
(set-session-transport-fd! session (fileno socket)))
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@findex session-record-port
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
Once a TLS session is established, data can be communicated through it
|
|
Packit |
549fdc |
(i.e., @emph{via} the TLS record layer) using the port returned by
|
|
Packit |
549fdc |
@code{session-record-port}:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
(let ((session (make-session connection-end/client)))
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;;
|
|
Packit |
549fdc |
;; Initialize the various parameters of SESSION, set up
|
|
Packit |
549fdc |
;; a network connection, etc.
|
|
Packit |
549fdc |
;;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
(let ((i/o (session-record-port session)))
|
|
Packit |
549fdc |
(display "Hello peer!" i/o)
|
|
Packit |
549fdc |
(let ((greetings (read i/o)))
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; @dots{}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
(bye session close-request/rdwr))))
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@c See <http://bugs.gnu.org/22966> for details.
|
|
Packit |
549fdc |
@cindex buffering
|
|
Packit |
549fdc |
Note that each write to the session record port leads to the
|
|
Packit |
549fdc |
transmission of an encrypted TLS ``Application Data'' packet. In the
|
|
Packit |
549fdc |
above example, we create an Application Data packet for the 11 bytes for
|
|
Packit |
549fdc |
the string that we write. This is not efficient both in terms of CPU
|
|
Packit |
549fdc |
usage and bandwidth (each packet adds at least 5 bytes of overhead and
|
|
Packit |
549fdc |
can lead to one @code{write} system call), so we recommend that
|
|
Packit |
549fdc |
applications do their own buffering.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@findex record-send
|
|
Packit |
549fdc |
@findex record-receive!
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
A lower-level I/O API is provided by @code{record-send} and
|
|
Packit |
549fdc |
@code{record-receive!} which take a bytevector (or a SRFI-4 vector) to
|
|
Packit |
549fdc |
represent the data sent or received. While it might improve
|
|
Packit |
549fdc |
performance, it is much less convenient than the session record port and
|
|
Packit |
549fdc |
should rarely be needed.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@node Exception Handling
|
|
Packit |
549fdc |
@section Exception Handling
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@cindex exceptions
|
|
Packit |
549fdc |
@cindex errors
|
|
Packit |
549fdc |
@cindex @code{gnutls-error}
|
|
Packit |
549fdc |
@findex error->string
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
GnuTLS errors are implemented as Scheme exceptions (@pxref{Exceptions,
|
|
Packit |
549fdc |
exceptions in Guile,, guile, The GNU Guile Reference Manual}). Each
|
|
Packit |
549fdc |
time a GnuTLS function returns an error, an exception with key
|
|
Packit |
549fdc |
@code{gnutls-error} is raised. The additional arguments that are
|
|
Packit |
549fdc |
thrown include an error code and the name of the GnuTLS procedure that
|
|
Packit |
549fdc |
raised the exception. The error code is pretty much like an enumerate
|
|
Packit |
549fdc |
value: it is one of the @code{error/} variables exported by the
|
|
Packit |
549fdc |
@code{(gnutls)} module (@pxref{Enumerates and Constants}). Exceptions
|
|
Packit |
549fdc |
can be turned into error messages using the @code{error->string}
|
|
Packit |
549fdc |
procedure.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
The following examples illustrates how GnuTLS exceptions can be
|
|
Packit |
549fdc |
handled:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
(let ((session (make-session connection-end/server)))
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;;
|
|
Packit |
549fdc |
;; ...
|
|
Packit |
549fdc |
;;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
(catch 'gnutls-error
|
|
Packit |
549fdc |
(lambda ()
|
|
Packit |
549fdc |
(handshake session))
|
|
Packit |
549fdc |
(lambda (key err function . currently-unused)
|
|
Packit |
549fdc |
(format (current-error-port)
|
|
Packit |
549fdc |
"a GnuTLS error was raised by `~a': ~a~%"
|
|
Packit |
549fdc |
function (error->string err)))))
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
Again, error values can be compared using @code{eq?}:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
;; `gnutls-error' handler.
|
|
Packit |
549fdc |
(lambda (key err function . currently-unused)
|
|
Packit |
549fdc |
(if (eq? err error/fatal-alert-received)
|
|
Packit |
549fdc |
(format (current-error-port)
|
|
Packit |
549fdc |
"a fatal alert was caught!~%")
|
|
Packit |
549fdc |
(format (current-error-port)
|
|
Packit |
549fdc |
"something bad happened: ~a~%"
|
|
Packit |
549fdc |
(error->string err))))
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
Note that the @code{catch} handler is currently passed only 3
|
|
Packit |
549fdc |
arguments but future versions might provide it with additional
|
|
Packit |
549fdc |
arguments. Thus, it must be prepared to handle more than 3 arguments,
|
|
Packit |
549fdc |
as in this example.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@c *********************************************************************
|
|
Packit |
549fdc |
@node Guile Examples
|
|
Packit |
549fdc |
@chapter Guile Examples
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
This chapter provides examples that illustrate common use cases.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@menu
|
|
Packit |
549fdc |
* Anonymous Authentication Guile Example:: Simplest client and server.
|
|
Packit |
549fdc |
@end menu
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@node Anonymous Authentication Guile Example
|
|
Packit |
549fdc |
@section Anonymous Authentication Guile Example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@dfn{Anonymous authentication} is very easy to use. No certificates
|
|
Packit |
549fdc |
are needed by the communicating parties. Yet, it allows them to
|
|
Packit |
549fdc |
benefit from end-to-end encryption and integrity checks.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
The client-side code would look like this (assuming @var{some-socket}
|
|
Packit |
549fdc |
is bound to an open socket port):
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@vindex connection-end/client
|
|
Packit |
549fdc |
@vindex kx/anon-dh
|
|
Packit |
549fdc |
@vindex close-request/rdwr
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
;; Client-side.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
(let ((client (make-session connection-end/client)))
|
|
Packit |
549fdc |
;; Use the default settings.
|
|
Packit |
549fdc |
(set-session-default-priority! client)
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Don't use certificate-based authentication.
|
|
Packit |
549fdc |
(set-session-certificate-type-priority! client '())
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Request the "anonymous Diffie-Hellman" key exchange method.
|
|
Packit |
549fdc |
(set-session-kx-priority! client (list kx/anon-dh))
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Specify the underlying socket.
|
|
Packit |
549fdc |
(set-session-transport-fd! client (fileno some-socket))
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Create anonymous credentials.
|
|
Packit |
549fdc |
(set-session-credentials! client
|
|
Packit |
549fdc |
(make-anonymous-client-credentials))
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Perform the TLS handshake with the server.
|
|
Packit |
549fdc |
(handshake client)
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Send data over the TLS record layer.
|
|
Packit |
549fdc |
(write "hello, world!" (session-record-port client))
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Terminate the TLS session.
|
|
Packit |
549fdc |
(bye client close-request/rdwr))
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
The corresponding server would look like this (again, assuming
|
|
Packit |
549fdc |
@var{some-socket} is bound to a socket port):
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@vindex connection-end/server
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@example
|
|
Packit |
549fdc |
;; Server-side.
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
(let ((server (make-session connection-end/server)))
|
|
Packit |
549fdc |
(set-session-default-priority! server)
|
|
Packit |
549fdc |
(set-session-certificate-type-priority! server '())
|
|
Packit |
549fdc |
(set-session-kx-priority! server (list kx/anon-dh))
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Specify the underlying transport socket.
|
|
Packit |
549fdc |
(set-session-transport-fd! server (fileno some-socket))
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Create anonymous credentials.
|
|
Packit |
549fdc |
(let ((cred (make-anonymous-server-credentials))
|
|
Packit |
549fdc |
(dh-params (make-dh-parameters 1024)))
|
|
Packit |
549fdc |
;; Note: DH parameter generation can take some time.
|
|
Packit |
549fdc |
(set-anonymous-server-dh-parameters! cred dh-params)
|
|
Packit |
549fdc |
(set-session-credentials! server cred))
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Perform the TLS handshake with the client.
|
|
Packit |
549fdc |
(handshake server)
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
;; Receive data over the TLS record layer.
|
|
Packit |
549fdc |
(let ((message (read (session-record-port server))))
|
|
Packit |
549fdc |
(format #t "received the following message: ~a~%"
|
|
Packit |
549fdc |
message)
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
(bye server close-request/rdwr)))
|
|
Packit |
549fdc |
@end example
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
This is it!
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@c *********************************************************************
|
|
Packit |
549fdc |
@node Guile Reference
|
|
Packit |
549fdc |
@chapter Guile Reference
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
This chapter lists the GnuTLS Scheme procedures exported by the
|
|
Packit |
549fdc |
@code{(gnutls)} module (@pxref{The Guile module system,,, guile, The
|
|
Packit |
549fdc |
GNU Guile Reference Manual}).
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@include core.c.texi
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@c Local Variables:
|
|
Packit |
549fdc |
@c ispell-local-dictionary: "american"
|
|
Packit |
549fdc |
@c End:
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@include cha-copying.texi
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@node Procedure Index
|
|
Packit |
549fdc |
@unnumbered Procedure Index
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@printindex fn
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@node Concept Index
|
|
Packit |
549fdc |
@unnumbered Concept Index
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@printindex cp
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
@bye
|