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