summaryrefslogtreecommitdiff
path: root/doc/gnutls-guile.texi
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-05-27 17:18:56 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-05-27 17:19:15 +0200
commit32d903954844c38a7f57e7d11f739a13e7c4580b (patch)
treed08fc4beba5d33c2f6a079f900297e90895be86a /doc/gnutls-guile.texi
parent1e00c52df333191fa0c64f37b9bca9c238b8388d (diff)
downloadgnutls-32d903954844c38a7f57e7d11f739a13e7c4580b.tar.gz
guile bindings added as a separate document.
Diffstat (limited to 'doc/gnutls-guile.texi')
-rw-r--r--doc/gnutls-guile.texi697
1 files changed, 697 insertions, 0 deletions
diff --git a/doc/gnutls-guile.texi b/doc/gnutls-guile.texi
new file mode 100644
index 0000000000..742611a04b
--- /dev/null
+++ b/doc/gnutls-guile.texi
@@ -0,0 +1,697 @@
+\input texinfo @c -*-texinfo-*-
+@comment %**start of header
+@setfilename gnutls-guile.info
+@include version.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, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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
+
+@ifnottex
+@node Top
+@top GnuTLS-Guile
+
+@insertcopying
+@end ifnottex
+
+@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.
+@end menu
+
+@node Preface
+@chapter Preface
+
+This manual describes the @uref{http://www.gnu.org/software/guile/,
+GNU Guile} Scheme programming interface to GnuTLS. The reader is
+assumed to have basic knowledge of the protocol and library. Details
+missing from this chapter may be found in @ref{Function reference,
+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 by default installed under the GnuTLS
+installation directory (e.g., 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
+guile> (use-modules (gnutls))
+<unnamed port>: no code for module (gnutls)
+guile>
+@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
+guile> (use-modules (gnutls))
+guile>
+@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{libguile-gnutls-v-0} similar to:
+
+@example
+gnutls.scm:361:1: In procedure dynamic-link in expression (load-extension "libguile-gnutls-v-0" "scm_init_gnutls"):
+gnutls.scm:361:1: file: "libguile-gnutls-v-0", message: "libguile-gnutls-v-0.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
+guile> (use-modules (gnutls))
+guile>
+@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
+guile> (use-modules (gnutls))
+guile> (gnutls-version)
+"@value{VERSION}"
+guile>
+@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)} and @code{(gnutls extra)} modules. 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_CRD_IA
+@} 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
+credentials/ia
+@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 and,
+similarly, procedures like @code{pkcs1-export-rsa-parameters} return
+binary data.
+
+@cindex SRFI-4
+@cindex homogeneous vector
+
+Binary data is represented on the Scheme side using SRFI-4 homogeneous
+vectors (@pxref{SRFI-4,,, guile, The GNU Guile Reference Manual}).
+Although any type of homogeneous vector may be used, @code{u8vector}s
+(i.e., vectors of bytes) are highly recommended.
+
+As an example, generating and then exporting RSA parameters in the PEM
+format can be done as follows:
+
+@findex make-rsa-parameters
+@findex pkcs1-export-rsa-parameters
+@vindex x509-certificate-format/pem
+
+@example
+(let* ((rsa-params (make-rsa-parameters 1024))
+ (raw-data
+ (pkcs1-export-rsa-parameters rsa-params
+ x509-certificate-format/pem)))
+ (uniform-vector-write raw-data (open-output-file "some-file.pem")))
+@end example
+
+For an example of OpenPGP key import from a file, see @ref{Importing
+OpenPGP Keys Guile 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)))
+ (write "Hello peer!" i/o)
+ (let ((greetings (read i/o)))
+
+ ;; ...
+
+ (bye session close-request/rdwr))))
+@end example
+
+@findex record-send
+@findex record-receive!
+
+A lower-level I/O API is provided by @code{record-send} and
+@code{record-receive!} which take an SRFI-4 vector to represent the
+data sent or received. While it might improve performance, it is much
+less convenient than the above 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.
+* OpenPGP Authentication Guile Example:: Using OpenPGP-based authentication.
+* Importing OpenPGP Keys Guile Example:: Importing keys from files.
+@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!
+
+
+@node OpenPGP Authentication Guile Example
+@section OpenPGP Authentication Guile Example
+
+GnuTLS allows users to authenticate using OpenPGP certificates. The
+relevant procedures are provided by the @code{(gnutls extra)} module.
+Using OpenPGP-based authentication is not more complicated than using
+anonymous authentication. It requires a bit of extra work, though, to
+import the OpenPGP public and private key of the client/server. Key
+import is omitted here and is left as an exercise to the reader
+(@pxref{Importing OpenPGP Keys Guile Example}).
+
+Assuming @var{some-socket} is bound to an open socket port and
+@var{pub} and @var{sec} are bound to the client's OpenPGP public and
+secret key, respectively, client-side code would look like this:
+
+@vindex certificate-type/openpgp
+
+@example
+;; Client-side.
+
+(define %certs (list certificate-type/openpgp))
+
+(let ((client (make-session connection-end/client))
+ (cred (make-certificate-credentials)))
+ (set-session-default-priority! client)
+
+ ;; Choose OpenPGP certificates.
+ (set-session-certificate-type-priority! client %certs)
+
+ ;; Prepare appropriate client credentials.
+ (set-certificate-credentials-openpgp-keys! cred pub sec)
+ (set-session-credentials! client cred)
+
+ ;; Specify the underlying transport socket.
+ (set-session-transport-fd! client (fileno some-socket))
+
+ (handshake client)
+ (write "hello, world!" (session-record-port client))
+ (bye client close-request/rdwr))
+@end example
+
+Similarly, server-side code would be along these lines:
+
+@example
+;; Server-side.
+
+(define %certs (list certificate-type/openpgp))
+
+(let ((server (make-session connection-end/server))
+ (rsa (make-rsa-parameters 1024))
+ (dh (make-dh-parameters 1024)))
+ (set-session-default-priority! server)
+
+ ;; Choose OpenPGP certificates.
+ (set-session-certificate-type-priority! server %certs)
+
+ (let ((cred (make-certificate-credentials)))
+ ;; Prepare credentials with RSA and Diffie-Hellman parameters.
+ (set-certificate-credentials-dh-parameters! cred dh)
+ (set-certificate-credentials-rsa-export-parameters! cred rsa)
+ (set-certificate-credentials-openpgp-keys! cred pub sec)
+ (set-session-credentials! server cred))
+
+ (set-session-transport-fd! server (fileno some-socket))
+
+ (handshake server)
+ (let ((msg (read (session-record-port server))))
+ (format #t "received: ~a~%" msg)
+
+ (bye server close-request/rdwr)))
+@end example
+
+In practice, generating RSA parameters (and Diffie-Hellman parameters)
+can time a long time. Thus, you may want to generate them once and
+store them in a file for future re-use (@pxref{Core Interface, @code{pkcs1-export-rsa-parameters} and @code{pkcs1-import-rsa-parameters}}).
+
+@node Importing OpenPGP Keys Guile Example
+@section Importing OpenPGP Keys Guile Example
+
+The following example provides a simple way of importing
+``ASCII-armored'' OpenPGP keys from files, using the
+@code{import-openpgp-certificate} and @code{import-openpgp-private-key}
+procedures provided by the @code{(gnutls extra)} module.
+
+@vindex openpgp-certificate-format/base64
+@vindex openpgp-certificate-format/raw
+
+@example
+(use-modules (srfi srfi-4)
+ (gnutls extra))
+
+(define (import-key-from-file import-proc file)
+ ;; Import OpenPGP key from FILE using IMPORT-PROC.
+
+ ;; Prepare a u8vector large enough to hold the raw
+ ;; key contents.
+ (let* ((size (stat:size (stat path)))
+ (raw (make-u8vector size)))
+
+ ;; Fill in the u8vector with the contents of FILE.
+ (uniform-vector-read! raw (open-input-file file))
+
+ ;; Pass the u8vector to the import procedure.
+ (import-proc raw openpgp-certificate-format/base64)))
+
+
+(define (import-public-key-from-file file)
+ (import-key-from-file import-openpgp-certificate file))
+
+(define (import-private-key-from-file file)
+ (import-key-from-file import-openpgp-private-key file))
+@end example
+
+The procedures @code{import-public-key-from-file} and
+@code{import-private-key-from-file} can be passed a file name. They
+return an OpenPGP public key and private key object, respectively
+(@pxref{Extra Interface, OpenPGP key objects}).
+
+
+@c *********************************************************************
+@node Guile Reference
+@chapter Guile Reference
+
+This chapter documents GnuTLS Scheme procedures available to Guile
+programmers.
+
+@menu
+* Core Interface:: Bindings for core GnuTLS.
+* Extra Interface:: Bindings for GnuTLS-Extra.
+@end menu
+
+@node Core Interface
+@section Core Interface
+
+This section lists the Scheme procedures exported by the
+@code{(gnutls)} module (@pxref{The Guile module system,,, guile, The
+GNU Guile Reference Manual}). This module is licenced under the GNU
+Lesser General Public Licence, version 2.1 or later.
+
+@include core.c.texi
+
+@node Extra Interface
+@section Extra Interface
+
+This section lists the Scheme procedures exported by the @code{(gnutls
+extra)} module. This module is licenced under the GNU General Public
+Licence, version 3 or later.
+
+@include extra.c.texi
+
+
+
+@ignore
+;;; arch-tag: ee5f2081-9153-48fc-b4ee-2024381c65d7
+@end ignore
+
+@c Local Variables:
+@c ispell-local-dictionary: "american"
+@c End:
+
+@node GNU Free Documentation License
+@appendix GNU Free Documentation License
+
+@cindex FDL, GNU Free Documentation License
+@include fdl-1.3.texi
+
+@bye