gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls-3_0_12-111-g8647efd


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls-3_0_12-111-g8647efd
Date: Sun, 29 Jan 2012 14:53:03 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=8647efdd4061998c6bf19f70de4ec78310e67741

The branch, master has been updated
       via  8647efdd4061998c6bf19f70de4ec78310e67741 (commit)
       via  68ec3fd879bbd683e73604c0fed5a759b35e2349 (commit)
       via  51066182d4cd4c2a5ac9124a786885524290886a (commit)
       via  ad12e726d44877303e61a8bd3989aef6cbda2cb4 (commit)
       via  6a541f6a85459b822695c7ba1c1ad2651315c3de (commit)
       via  e45eeba9ea262d0b476f280188e2031c541ee19e (commit)
       via  d1e72335d8ab29a94e7b42f63ce74af0c39ff898 (commit)
       via  0fcf4c8bd71df103f56bd532b64cbb5466381546 (commit)
       via  efaa2ee176568fcd009ff2ca9daa1b7fdac4c491 (commit)
       via  df00c7b030248bc8fc061667e64d21bc3c6fcef7 (commit)
       via  2b1336e8109a5fdac6c587274733b0e8b33bda21 (commit)
       via  46a97ed3f606593848832da019734fc12760276c (commit)
       via  030d8783c815aa4bababe7cca8ff538762f5a2f3 (commit)
      from  dc42971afc5051136ebc8d4b21cb49a2055d4a7b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 8647efdd4061998c6bf19f70de4ec78310e67741
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Jan 29 15:57:34 2012 +0100

    updated text

commit 68ec3fd879bbd683e73604c0fed5a759b35e2349
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Jan 29 15:55:12 2012 +0100

    removed debugging code

commit 51066182d4cd4c2a5ac9124a786885524290886a
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Jan 29 15:52:48 2012 +0100

    gnutls_ocsp_resp_verify_direct() will use the intermediate certificates
    in the response in order to verify the validity, thus aligning its 
functionality
    with gnutls_ocsp_resp_verify().

commit ad12e726d44877303e61a8bd3989aef6cbda2cb4
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Jan 29 15:52:19 2012 +0100

    cleanup a bit the printing information stuff.

commit 6a541f6a85459b822695c7ba1c1ad2651315c3de
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Jan 29 14:20:07 2012 +0100

    corrected dependencies

commit e45eeba9ea262d0b476f280188e2031c541ee19e
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Jan 29 14:08:07 2012 +0100

    Manual pages for included programs are auto-generated using the autoopts 
definitions.

commit d1e72335d8ab29a94e7b42f63ce74af0c39ff898
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Jan 29 12:38:23 2012 +0100

    corrected dependencies

commit 0fcf4c8bd71df103f56bd532b64cbb5466381546
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jan 28 19:55:45 2012 +0100

    gnutls-cli will try to verify ocsp responses if --ocsp is given.

commit efaa2ee176568fcd009ff2ca9daa1b7fdac4c491
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jan 28 18:55:55 2012 +0100

    Added gnutls_ocsp_resp_verify() and some sign fixes.

commit df00c7b030248bc8fc061667e64d21bc3c6fcef7
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jan 28 17:16:25 2012 +0100

    updated todo

commit 2b1336e8109a5fdac6c587274733b0e8b33bda21
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jan 28 17:14:48 2012 +0100

    updated text.

commit 46a97ed3f606593848832da019734fc12760276c
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jan 28 17:14:37 2012 +0100

    Do not store a key when it already exists.

commit 030d8783c815aa4bababe7cca8ff538762f5a2f3
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jan 28 13:48:50 2012 +0100

    ssh flag is has the option to be disabled/enabled.

-----------------------------------------------------------------------

Summary of changes:
 NEWS                         |   10 +-
 doc/Makefile.am              |   42 +++
 doc/TODO                     |    2 +-
 doc/cha-cert-auth2.texi      |  663 +-----------------------------------------
 doc/cha-gtls-app.texi        |    2 +-
 doc/cha-programs.texi        |  397 +------------------------
 doc/cha-shared-key.texi      |   72 +-----
 doc/examples/ex-verify-ssh.c |    7 +-
 doc/manpages/Makefile.am     |   32 +-
 lib/auth/cert.h              |    4 +-
 lib/includes/gnutls/ocsp.h   |   12 +-
 lib/libgnutls.map            |    1 +
 lib/openpgp/openpgp_int.h    |    2 +-
 lib/x509/ocsp.c              |  265 ++++++++++++-----
 lib/x509/ocsp_output.c       |    4 +-
 src/Makefile.am              |   20 +-
 src/certtool-args.def.in     |  231 ++++++++++++++-
 src/cli-args.def.in          |   16 +
 src/cli-debug-args.def.in    |   61 ++++-
 src/cli.c                    |  108 +++++++-
 src/common.c                 |   42 ++--
 src/common.h                 |    4 +-
 src/ocsptool-args.def.in     |  140 +++++++++-
 src/ocsptool-common.c        |  364 +++++++++++++++++++++++
 src/ocsptool-common.h        |   13 +
 src/ocsptool.c               |  272 +----------------
 src/p11tool-args.def.in      |    2 +-
 src/psk-args.def.in          |   11 +-
 src/serv-args.def.in         |  174 +++++++++++-
 src/serv.c                   |    6 +-
 src/srptool-args.def.in      |    2 +-
 src/tests.c                  |    2 +-
 32 files changed, 1440 insertions(+), 1543 deletions(-)
 create mode 100644 src/ocsptool-common.c

diff --git a/NEWS b/NEWS
index ccce513..55c60cc 100644
--- a/NEWS
+++ b/NEWS
@@ -4,7 +4,13 @@ See the end for copying conditions.
 
 * Version 3.0.13 (unreleased)
 
-** gnutls-cli: If no --x509cafile is provided a default is
+** gnutls-cli: added the --ocsp option which will verify
+the peer's certificate with OCSP.
+
+** gnutls-cli: added the --ssh and if specified, gnutls-cli
+will use an ssh-style authentication method.
+
+** gnutls-cli: if no --x509cafile is provided a default is
 assumed (/etc/ssl/certs/ca-certificates.crt).
 
 ** ocsptool: Added --ask parameter, to verify a certificate's
@@ -31,7 +37,7 @@ when stored as a 'general name' and serial combo.
 
 ** libgnutls: Added function to force explicit reinitialization
 of PKCS #11 modules. This is required on the child process after
-a fork.
+a fork (if PKCS #11 functionality is desirable).
 
 ** API and ABI modifications:
 gnutls_verify_stored_pubkey: Added
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 9b7764b..edf45a3 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -28,6 +28,44 @@ if ENABLE_GTK_DOC
 SUBDIRS += reference
 endif
 
+invoke-gnutls-cli.texi: ../src/cli-args.def
+       cd ../src/ && autogen -Tagtexi-cmd.tpl $<
+       mv ../src/$@ .
+
+invoke-gnutls-cli-debug.texi: ../src/cli-debug-args.def
+       cd ../src/ && autogen -Tagtexi-cmd.tpl $<
+       mv ../src/$@ .
+
+invoke-gnutls-serv.texi: ../src/serv-args.def
+       cd ../src/ && autogen -Tagtexi-cmd.tpl $<
+       mv ../src/$@ .
+
+invoke-certtool.texi: ../src/certtool-args.def
+       cd ../src/ && autogen -Tagtexi-cmd.tpl $<
+       mv ../src/$@ .
+
+invoke-srptool.texi: ../src/srptool-args.def
+       cd ../src/ && autogen -Tagtexi-cmd.tpl $<
+       mv ../src/$@ .
+       sed -i 's/@subsection/@subsubsection/' $@
+       sed -i 's/@section/@subsection/' $@
+
+invoke-ocsptool.texi: ../src/ocsptool-args.def
+       cd ../src/ && autogen -Tagtexi-cmd.tpl $<
+       mv ../src/$@ .
+
+invoke-psktool.texi: ../src/psk-args.def
+       cd ../src/ && autogen -Tagtexi-cmd.tpl $<
+       mv ../src/$@ .
+       sed -i 's/@subsection/@subsubsection/' $@
+       sed -i 's/@section/@subsection/' $@
+
+invoke-p11tool.texi: ../src/p11tool-args.def
+       cd ../src/ && autogen -Tagtexi-cmd.tpl $<
+       mv ../src/$@ .
+       sed -i 's/@subsection/@subsubsection/' $@
+       sed -i 's/@section/@subsection/' $@
+
 info_TEXINFOS = gnutls.texi gnutls-guile.texi
 gnutls_TEXINFOS = gnutls.texi fdl-1.3.texi                             \
        cha-bib.texi cha-cert-auth.texi cha-cert-auth2.texi             \
@@ -37,6 +75,10 @@ gnutls_TEXINFOS = gnutls.texi fdl-1.3.texi                   
        \
        sec-tls-app.texi cha-errors.texi cha-support.texi               \
        cha-shared-key.texi cha-gtls-examples.texi
 
+gnutls_TEXINFOS += invoke-gnutls-cli.texi invoke-gnutls-cli-debug.texi \
+       invoke-gnutls-serv.texi invoke-certtool.texi invoke-srptool.texi \
+       invoke-ocsptool.texi invoke-psktool.texi invoke-p11tool.texi
+
 # Examples.
 gnutls_TEXINFOS += examples/ex-client-anon.c                           \
        examples/ex-session-info.c examples/ex-verify.c                 \
diff --git a/doc/TODO b/doc/TODO
index 323e124..655b5cf 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -10,7 +10,7 @@ Current list:
   RSA but rather the combination of RSA-SHA256, RSA-SHA1 etc.
   That will allow the usage of more secure tokens that do not
   allow plain RSA.
-* Support PKCS#8 AES and DES-MD5 (tests/enc3pkcs8.pem) encrypted keys.
+* Support PKCS#8 DES-MD5 (tests/enc3pkcs8.pem) encrypted keys.
   (openssl seems to use DES-MD5 to encrypt keys by default)
 * Add support for generating empty CRLs
 * Document the format for the supported DN attributes.
diff --git a/doc/cha-cert-auth2.texi b/doc/cha-cert-auth2.texi
index 251d73f..9d246b0 100644
--- a/doc/cha-cert-auth2.texi
+++ b/doc/cha-cert-auth2.texi
@@ -12,8 +12,8 @@ structures, etc., are discussed in this chapter.
 * PKIX certificate revocation lists::
 * OCSP certificate status checking::
 * Managing encrypted keys::
-* The certtool application::
-* The ocsptool application::
+* certtool Invocation::            Invoking certtool
+* ocsptool Invocation::            Invoking ocsptool
 * Smart cards and HSMs::
 * Abstract key types::
 @end menu
@@ -351,565 +351,9 @@ of their usage is also shown.
 
 @verbatiminclude examples/ex-pkcs12.c
 
address@hidden The certtool application
address@hidden The certtool application
address@hidden certtool
address@hidden invoke-certtool.texi
 
-This is a program to generate @acronym{X.509} certificates, certificate
-requests, CRLs and private keys.
-
address@hidden
-Certtool help
-Usage: certtool [options]
-     -s, --generate-self-signed 
-                              Generate a self-signed certificate.
-     -c, --generate-certificate 
-                              Generate a signed certificate.
-     --generate-proxy         Generate a proxy certificate.
-     --generate-crl           Generate a CRL.
-     -u, --update-certificate 
-                              Update a signed certificate.
-     -p, --generate-privkey   Generate a private key.
-     -q, --generate-request   Generate a PKCS #10 certificate 
-                              request.
-     -e, --verify-chain       Verify a PEM encoded certificate chain. 
-                              The last certificate in the chain must 
-                              be a self signed one.
-     --verify                 Verify a PEM encoded certificate chain. 
-                              CA certificates must be loaded with 
-                              --load-ca-certificate.
-     --verify-crl             Verify a CRL.
-     --generate-dh-params     Generate PKCS #3 encoded Diffie-Hellman 
-                              parameters.
-     --get-dh-params          Get the included PKCS #3 encoded 
-                              Diffie-Hellman parameters.
-     --load-privkey FILE      Private key file to use.
-     --load-pubkey FILE       Public key file to use.
-     --load-request FILE      Certificate request file to use.
-     --load-certificate FILE  
-                              Certificate file to use.
-     --load-ca-privkey FILE   Certificate authority's private key 
-                              file to use.
-     --load-ca-certificate FILE  
-                              Certificate authority's certificate 
-                              file to use.
-     --password PASSWORD      Password to use.
-     -i, --certificate-info   Print information on a certificate.
-     --certificate-pubkey     Print certificate public key.
-     --pgp-certificate-info   Print information on a OpenPGP 
-                              certificate.
-     --pgp-ring-info          Print information on a keyring 
-                              structure.
-     -l, --crl-info           Print information on a CRL.
-     --crq-info               Print information on a Certificate 
-                              Request.
-     --no-crq-extensions      Do not use extensions in certificate 
-                              requests.
-     --p12-info               Print information on a PKCS #12 
-                              structure.
-     --p7-info                Print information on a PKCS #7 
-                              structure.
-     --smime-to-p7            Convert S/MIME to PKCS #7 structure.
-     -k, --key-info           Print information on a private key.
-     --pgp-key-info           Print information on a OpenPGP private 
-                              key.
-     --pubkey-info            Print information on a public key.
-     --fix-key                Regenerate the parameters in a private 
-                              key.
-     --v1                     Generate an X.509 version 1 certificate 
-                              (no extensions).
-     --to-p12                 Generate a PKCS #12 structure.
-     --to-p8                  Generate a PKCS #8 key structure.
-     -8, --pkcs8              Use PKCS #8 format for private keys.
-     --dsa                    Use DSA keys.
-     --ecc                    Use ECC (ECDSA) keys.
-     --hash STR               Hash algorithm to use for signing 
-                              (MD5,SHA1,RMD160,SHA256,SHA384,SHA512).
-     --export-ciphers         Use weak encryption algorithms.
-     --inder                  Use DER format for input certificates 
-                              and private keys.
-     --inraw                  Use RAW/DER format for input 
-                              certificates and private keys.
-     --outder                 Use DER format for output certificates 
-                              and private keys.
-     --outraw                 Use RAW/DER format for output 
-                              certificates and private keys.
-     --bits BITS              specify the number of bits for key 
-                              generation.
-     --sec-param PARAM        specify the security level 
-                              [low|normal|high|ultra].
-     --disable-quick-random   Use /dev/random for key generationg, 
-                              thus increasing the quality of 
-                              randomness used.
-     --outfile FILE           Output file.
-     --infile FILE            Input file.
-     --template FILE          Template file to use for non 
-                              interactive operation.
-     --pkcs-cipher CIPHER     Cipher to use for pkcs operations 
-                              (3des,3des-pkcs12,aes-128,aes-192,aes-25
-                              6,rc2-40,arcfour).
-     -d, --debug LEVEL        specify the debug level. Default is 1.
-     -h, --help               shows this help text
-     -v, --version            shows the program's version
address@hidden example
-
-The program can be used interactively or non interactively by
-specifying the @code{--template} command line option. See below for an
-example of a template file.
-
address@hidden Diffie-Hellman parameter generation
-To generate parameters for Diffie-Hellman key exchange, use the command:
address@hidden
-$ certtool --generate-dh-params --outfile dh.pem --sec-param normal
address@hidden example
-
address@hidden Self-signed certificate generation
-
-To create a self signed certificate, use the command:
address@hidden
-$ certtool --generate-privkey --outfile ca-key.pem
-$ certtool --generate-self-signed --load-privkey ca-key.pem \
-   --outfile ca-cert.pem
address@hidden example
-
-Note that a self-signed certificate usually belongs to a certificate
-authority, that signs other certificates.
-
address@hidden Private key generation
-To create a private key (RSA by default), run:
-
address@hidden
-$ certtool --generate-privkey --outfile key.pem
address@hidden example
-
-To create a DSA or elliptic curves (ECDSA) private key use the
-above command combined with @code{--dsa} or @code{--ecc} options.
-
address@hidden Certificate generation
-To generate a certificate using the private key, use the command:
-
address@hidden
-$ certtool --generate-certificate --load-privkey key.pem \
-   --outfile cert.pem --load-ca-certificate ca-cert.pem \
-   --load-ca-privkey ca-key.pem
address@hidden example
-
-Alternatively you may create a certificate request, which is needed
-when the certificate will be signed by a third party authority.
-
address@hidden
-$ certtool --generate-request --load-privkey key.pem \
-  --outfile request.pem
address@hidden example
-
-If the private key is stored in a smart card you can generate
-a request by specifying the private key object URL (see @ref{The p11tool 
application}
-on how to obtain the URL).
-
address@hidden
-$ certtool --generate-request --load-privkey pkcs11:(PRIVKEY URL) \
-  --load-pubkey pkcs11:(PUBKEY URL) --outfile request.pem
address@hidden example
-
-To generate a certificate using the previous request, use the command:
-
address@hidden
-$ certtool --generate-certificate --load-request request.pem \
-   --outfile cert.pem \
-   --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem
address@hidden example
-
address@hidden Certificate information
-To view the certificate information, use:
-
address@hidden
-$ certtool --certificate-info --infile cert.pem
address@hidden example
-
address@hidden @acronym{PKCS} #12 structure generation
-To generate a @acronym{PKCS} #12 structure using the previous key and
-certificate, use the command:
-
address@hidden
-$ certtool --load-certificate cert.pem --load-privkey key.pem \
-  --to-p12 --outder --outfile key.p12
address@hidden example
-
-Some tools (reportedly web browsers) have problems with that file
-because it does not contain the CA certificate for the certificate.
-To work around that problem in the tool, you can use the
---load-ca-certificate parameter as follows:
-
address@hidden
-$ certtool --load-ca-certificate ca.pem \
-  --load-certificate cert.pem --load-privkey key.pem \
-  --to-p12 --outder --outfile key.p12
address@hidden example
-
address@hidden Proxy certificate generation
-Proxy certificate can be used to delegate your credential to a
-temporary, typically short-lived, certificate.  To create one from the
-previously created certificate, first create a temporary key and then
-generate a proxy certificate for it, using the commands:
-
address@hidden
-$ certtool --generate-privkey > proxy-key.pem
-$ certtool --generate-proxy --load-ca-privkey key.pem \
-  --load-privkey proxy-key.pem --load-certificate cert.pem \
-  --outfile proxy-cert.pem
address@hidden example
-
address@hidden Certificate revocation list generation
-To create an empty Certificate Revocation List (CRL) do:
-
address@hidden
-$ certtool --generate-crl --load-ca-privkey x509-ca-key.pem \
-           --load-ca-certificate x509-ca.pem
address@hidden example
-
-To create a CRL that contains some revoked certificates, place the
-certificates in a file and use @code{--load-certificate} as follows:
-
address@hidden
-$ certtool --generate-crl --load-ca-privkey x509-ca-key.pem \
-  --load-ca-certificate x509-ca.pem --load-certificate revoked-certs.pem
address@hidden example
-
-To verify a Certificate Revocation List (CRL) do:
-
address@hidden
-$ certtool --verify-crl --load-ca-certificate x509-ca.pem < crl.pem
address@hidden example
-
-
-
address@hidden Certtool's template file format:
-A template file can be used to avoid the interactive questions of
-certtool. Initially create a file named 'cert.cfg' that contains the 
information
-about the certificate. The template can be used as below:
-
address@hidden
-$ certtool --generate-certificate cert.pem --load-privkey key.pem  \
-   --template cert.cfg \
-   --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem
address@hidden example
-
-An example certtool template file that can be used to generate a certificate
-request or a self signed certificate follows.
-
address@hidden
-# X.509 Certificate options
-#
-# DN options
-
-# The organization of the subject.
-organization = "Koko inc."
-
-# The organizational unit of the subject.
-unit = "sleeping dept."
-
-# The locality of the subject.
-# locality =
-
-# The state of the certificate owner.
-state = "Attiki"
-
-# The country of the subject. Two letter code.
-country = GR
-
-# The common name of the certificate owner.
-cn = "Cindy Lauper"
-
-# A user id of the certificate owner.
-#uid = "clauper"
-
-# If the supported DN OIDs are not adequate you can set
-# any OID here.
-# For example set the X.520 Title and the X.520 Pseudonym
-# by using OID and string pairs.
-#dn_oid = 2.5.4.12 Dr. 
-#dn_oid = 2.5.4.65 jackal
-
-# This is deprecated and should not be used in new
-# certificates.
-# pkcs9_email = "none@@none.org"
-
-# The serial number of the certificate
-serial = 007
-
-# In how many days, counting from today, this certificate will expire.
-expiration_days = 700
-
-# X.509 v3 extensions
-
-# A dnsname in case of a WWW server.
-#dns_name = "www.none.org"
-#dns_name = "www.morethanone.org"
-
-# An IP address in case of a server.
-#ip_address = "192.168.1.1"
-
-# An email in case of a person
-email = "none@@none.org"
-
-# Challenge password used in certificate requests
-challenge_passwd = 123456
-
-# key_purpose_oid = 1.2.3.4.5.6.7
-# key_purpose_oid = 1.2.3.4.5.6.7.9
-
-# An URL that has CRLs (certificate revocation lists)
-# available. Needed in CA certificates.
-#crl_dist_points = "http://www.getcrl.crl/getcrl/";
-
-# Whether this is a CA certificate or not
-#ca
-
-# Whether this certificate will be used for a TLS client
-#tls_www_client
-
-# Whether this certificate will be used for a TLS server
-#tls_www_server
-
-# Whether this certificate will be used to sign data (needed
-# in TLS DHE ciphersuites).
-signing_key
-
-# Whether this certificate will be used to encrypt data (needed
-# in TLS RSA ciphersuites). Note that it is preferred to use different
-# keys for encryption and signing.
-#encryption_key
-
-# Whether this key will be used to sign other certificates.
-#cert_signing_key
-
-# Whether this key will be used to sign CRLs.
-#crl_signing_key
-
-# Whether this key will be used to sign code.
-#code_signing_key
-
-# Whether this key will be used to sign OCSP data.
-#ocsp_signing_key
-
-# Whether this key will be used for time stamping.
-#time_stamping_key
-
-# Whether this key will be used for IPsec IKE operations.
-#ipsec_ike_key
-
-# When generating a certificate from a certificate
-# request, then honor the extensions stored in the request
-# and store them in the real certificate.
-#honor_crq_extensions
-
-# Path length contraint. Sets the maximum number of
-# certificates that can be used to certify this certificate.
-# (i.e. the certificate chain length)
-#path_len = -1
-#path_len = 2
-
-# Options for proxy certificates
-# proxy_policy_language = 1.3.6.1.5.5.7.21.1
-
-# Options for generating a CRL
-
-# next CRL update will be in 43 days (wow)
-#crl_next_update = 43
-
-# this is the 5th CRL by this CA
-#crl_number = 5
-
address@hidden example
-
address@hidden The ocsptool application
address@hidden The ocsptool application
address@hidden ocsptool
-
-This is a program that can parse and print information about
address@hidden requests/responses, generate requests and verify
-responses.
-
address@hidden
-Ocsptool help
-Usage : ocsptool [options]
-     -e, --verify-response    Verify response.
-     -i, --request-info       Print information on a OCSP request.
-     -j, --response-info      Print information on a OCSP response.
-     -q, --generate-request   Generate a OCSP request.
-     --no-nonce               don't add nonce to OCSP request.
-     --load-issuer FILE       read issuer certificate from FILE.
-     --load-cert FILE         read certificate to check from FILE.
-     --load-trust FILE        read trust anchors from FILE.
-     --inder                  Use DER format for input certificates.
-     -Q, --load-request FILE
-                              read DER encoded OCSP request from
-                              FILE.
-     -S, --load-response FILE
-                              read DER encoded OCSP response from
-                              FILE.
-     --outfile FILE           Output file.
-     --infile FILE            Input file.
-     -V, --verbose            More verbose output.
-     -d, --debug integer      Enable debugging
-     -v, --version            prints the program's version number
-     -h, --help               shows this help text
address@hidden example
-
address@hidden Print information about an OCSP request
-
-To parse an OCSP request and print information about the content, the
address@hidden or @code{--request-info} parameter may be used as follows.
-The @code{-Q} parameter specify the name of the file containing the
-OCSP request, and it should contain the OCSP request in binary DER
-format.
-
address@hidden
-$ ocsptool -i -Q ocsp-request.der
address@hidden example
-
-The input file may also be sent to standard input like this:
-
address@hidden
-$ cat ocsp-request.der | ocsptool --request-info
address@hidden example
-
address@hidden Print information about an OCSP response
-
-Similar to parsing OCSP requests, OCSP responses can be parsed using
-the @code{-j} or @code{--response-info} as follows.
-
address@hidden
-$ ocsptool -j -Q ocsp-response.der
-$ cat ocsp-response.der | ocsptool --response-info
address@hidden example
-
address@hidden Generate an OCSP request
-
-The @code{-q} or @code{--generate-request} parameters are used to
-generate an OCSP request.  By default the OCSP request is written to
-standard output in binary DER format, but can be stored in a file
-using @code{--outfile}.  To generate an OCSP request the issuer of the
-certificate to check needs to be specified with @code{--load-issuer}
-and the certificate to check with @code{--load-cert}.  By default PEM
-format is used for these files, although @code{--inder} can be used to
-specify that the input files are in DER format.
-
address@hidden
-$ ocsptool -q --load-issuer issuer.pem --load-cert client.pem --outfile 
ocsp-request.der
address@hidden example
-
-When generating OCSP requests, the tool will add an OCSP extension
-containing a nonce.  This behaviour can be disabled by specifying
address@hidden
-
address@hidden Verify signature in OCSP response
-
-To verify the signature in an OCSP response the @code{-e} or
address@hidden parameter is used.  The tool will read an
-OCSP response in DER format from standard input, or from the file
-specified by @code{--load-response}.  The OCSP response is verified
-against a set of trust anchors, which are specified using
address@hidden  The trust anchors are concatenated certificates
-in PEM format.  The certificate that signed the OCSP response needs to
-be in the set of trust anchors, or the issuer of the signer
-certificate needs to be in the set of trust anchors and the OCSP
-Extended Key Usage bit has to be asserted in the signer certificate.
-
address@hidden
-$ ocsptool -e --load-trust issuer.pem --load-response ocsp-response.der
address@hidden example
-
-The tool will print status of verification.
-
address@hidden Verify signature in OCSP response against given certificate
-
-It is possible to override the normal trust logic if you know that a
-certain certificate is supposed to have signed the OCSP response, and
-you want to use it to check the signature.  This is achieved using
address@hidden instead of @code{--load-trust}.  This will load
-one certificate and it will be used to verify the signature in the
-OCSP response.  It will not check the Extended Key Usage bit.
-
address@hidden
-$ ocsptool -e --load-signer ocsp-signer.pem --load-response ocsp-response.der
address@hidden example
-
-This approach is normally only relevant in two situations.  The first
-is when the OCSP response does not contain a copy of the signer
-certificate, so the @code{--load-trust} code would fail.  The second
-is if you want to avoid the indirect mode where the OCSP response
-signer certificate is signed by a trust anchor.
-
address@hidden Real-world example
-
-Here is an example of how to generate an OCSP request for a
-certificate and to verify the response.  For illustration we'll use
-the @code{blog.josefsson.org} host, which (as of writing) uses a
-certificate from CACert.  First we'll use @code{gnutls-cli} to get a
-copy of the server certificate chain.  The server is not required to
-send this information, but this particular one is configured to do so.
-
address@hidden
-$ echo | gnutls-cli -p 443 blog.josefsson.org --print-cert > chain.pem
address@hidden example
-
-Use a text editor on @code{chain.pem} to create three files for each
-separate certificates, called @code{cert.pem} for the first
-certificate for the domain itself, secondly @code{issuer.pem} for the
-intermediate certificate and @code{root.pem} for the final root
-certificate.
-
-The domain certificate normally contains a pointer to where the OCSP
-responder is located, in the Authority Information Access Information
-extension.  For example, from @code{certtool -i < cert.pem} there is
-this information:
-
address@hidden
-               Authority Information Access Information (not critical):
-                       Access Method: 1.3.6.1.5.5.7.48.1 (id-ad-ocsp)
-                       Access Location URI: http://ocsp.CAcert.org/
address@hidden example
-
-This means the CA support OCSP queries over HTTP.  We are now ready to
-create a OCSP request for the certificate.
-
address@hidden
-$ ocsptool --generate-request --load-issuer issuer.pem  --load-cert cert.pem 
--outfile ocsp-request.der
address@hidden example
-
-The request is sent base64 encoded via HTTP to the address indicated
-by the id-ad-ocsp extension, as follows.
-
address@hidden
-$ wget -O ocsp-response.der http://ocsp.CAcert.org/$(base64 -w0 
ocsp-request.der)
address@hidden example
-
-The OCSP response is now in the file @code{ocsp-response.der} and you
-can view it using @code{ocsptool -j < ocsp-response.der}.  To verify
-the signature you need to load the issuer as the trust anchor.
-
address@hidden
-$ ocsptool --verify-response --load-trust issuer.pem --load-response 
ocsp-response.der
-Verifying OCSP Response: Success.
-$
address@hidden example
-
-This particular OCSP responder includes its signer certificate in the
-OCSP respnose, so you may extract it and use it together with
address@hidden for verifying the signature directly against the
-certificate.
-
address@hidden
-$ ocsptool -j < ocsp-response.der > signer.pem
-$ ocsptool --verify-response --load-signer signer.pem --load-response 
ocsp-response.der
-Verifying OCSP Response: Success.
-$
address@hidden example
-
-You may experiment passing different certificates to
address@hidden and @code{--load-signer} to find common error
-conditions for OCSP response verification failures.
address@hidden invoke-ocsptool.texi
 
 @node Smart cards and HSMs
 @section Smart cards and HSMs
@@ -954,7 +398,7 @@ system, being the @acronym{Gnome Keyring}.
 * Reading objects::
 * Writing objects::
 * Using a PKCS11 token with TLS::
-* The p11tool application::
+* p11tool Invocation::             Invoking p11tool
 @end menu
 
 @node PKCS11 Initialization
@@ -1078,102 +522,7 @@ certificates by specifying a PKCS #11 URL instead of a 
filename.
 
 
@showfuncC{gnutls_certificate_set_x509_trust_file,gnutls_certificate_set_x509_key_file,gnutls_certificate_set_x509_simple_pkcs12_file}
 
address@hidden The p11tool application
address@hidden The p11tool application
address@hidden
address@hidden p11tool
-
-p11tool is a program that is used to access tokens
-and security modules that support the PKCS #11 API. It requires
-individual PKCS #11 modules to be loaded either with the
address@hidden option, or by setting up the GnuTLS configuration
-file for PKCS #11 as in @ref{Smart cards and HSMs}.
-
address@hidden
-p11tool help
-Usage: p11tool [options]
-Usage: p11tool --list-tokens
-Usage: p11tool --list-all
-Usage: p11tool --export 'pkcs11:...'
-
-     --export URL             Export an object specified by a pkcs11 
-                              URL
-     --list-tokens            List all available tokens
-     --list-mechanisms URL    List all available mechanisms in token.
-     --list-all               List all objects specified by a PKCS#11 
-                              URL
-     --list-all-certs         List all certificates specified by a 
-                              PKCS#11 URL
-     --list-certs             List certificates that have a private 
-                              key specified by a PKCS#11 URL
-     --list-privkeys          List private keys specified by a 
-                              PKCS#11 URL
-     --list-trusted           List certificates marked as trusted, 
-                              specified by a PKCS#11 URL
-     --initialize URL         Initializes a PKCS11 token.
-     --write URL              Writes loaded certificates, private or 
-                              secret keys to a PKCS11 token.
-     --delete URL             Deletes objects matching the URL.
-     --label label            Sets a label for the write operation.
-     --trusted                Marks the certificate to be written as 
-                              trusted.
-     --private                Marks the object to be written as 
-                              private (requires PIN).
-     --no-private             Marks the object to be written as not 
-                              private.
-     --login                  Force login to token
-     --detailed-url           Export detailed URLs.
-     --no-detailed-url        Export less detailed URLs.
-     --secret-key HEX_KEY     Provide a hex encoded secret key.
-     --load-privkey FILE      Private key file to use.
-     --load-pubkey FILE       Private key file to use.
-     --load-certificate FILE  
-                              Certificate file to use.
-     -8, --pkcs8              Use PKCS #8 format for private keys.
-     --inder                  Use DER format for input certificates 
-                              and private keys.
-     --inraw                  Use RAW/DER format for input 
-                              certificates and private keys.
-     --provider Library       Specify the pkcs11 provider library
-     --outfile FILE           Output file.
-     -d, --debug LEVEL        specify the debug level. Default is 1.
-     -h, --help               shows this help text
address@hidden example
-
-After being provided the available PKCS #11 modules, it can list all tokens 
-available in your system, the objects on the tokens, and perform operations
-on them.
-
-Some examples on how to use p11tool are illustrated in the following  
paragraphs.
-
address@hidden List all tokens
address@hidden
-$ p11tool --list-tokens
address@hidden example
-
address@hidden List all objects
-The following command will list all objects in a token. The @code{--login}
-is required to show objects marked as private.
address@hidden
-$ p11tool --login --list-all
address@hidden example
-
address@hidden Exporting an object
-To retrieve an object stored in the card use the following command.
-Note however that objects marked as sensitive (typically PKCS #11 private 
keys) 
-are not allowed to be extracted from the token.
address@hidden 
-$ p11tool --login --export [OBJECT URL]
address@hidden example
-
address@hidden Copy an object to a token
-To copy an object, such as a certificate or private key to a token
-use the following command.
address@hidden 
-$ p11tool --login --write [TOKEN URL] \
-  --load-certificate cert.pem --label "my_cert"
address@hidden example
-
address@hidden invoke-p11tool.texi
 
 @node Abstract key types
 @section Abstract key types
diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi
index f716bb8..9207c26 100644
--- a/doc/cha-gtls-app.texi
+++ b/doc/cha-gtls-app.texi
@@ -935,7 +935,7 @@ will allow V1 CAs in chains.
 @end float
 
 Finally the ciphersuites enabled by any priority string can be
-listed using the @code{gnutls-cli} application (see @ref{The gnutls-cli 
tool}), 
+listed using the @code{gnutls-cli} application (see @ref{gnutls-cli 
Invocation}), 
 or by using the priority functions as in @ref{Listing the ciphersuites in a 
priority string}.
 
 Example priority strings are:
diff --git a/doc/cha-programs.texi b/doc/cha-programs.texi
index bf08d29..4526747 100644
--- a/doc/cha-programs.texi
+++ b/doc/cha-programs.texi
@@ -6,393 +6,14 @@ let you use the library for common tasks without writing an
 application.  The applications are discussed in this chapter.
 
 @menu
-* The gnutls-cli tool::
-* The gnutls-serv tool::
-* The gnutls-cli-debug tool::
+* gnutls-cli Invocation::          Invoking gnutls-cli
+* gnutls-serv Invocation::         Invoking gnutls-serv
+* gnutls-cli-debug Invocation::    Invoking gnutls-cli-debug
 @end menu
address@hidden @include invoke-gnutls-cli.menu
address@hidden @include invoke-gnutls-serv.menu
address@hidden @include invoke-gnutls-cli-debug.menu
 
address@hidden The gnutls-cli tool
address@hidden The gnutls-cli tool
address@hidden gnutls-cli
-
-Simple client program to set up a TLS connection to some other
-computer.  It sets up a TLS connection and forwards data from the
-standard input to the secured socket and vice versa.
-
address@hidden
-GnuTLS test client
-Usage:  gnutls-cli [options] hostname
-
-     -d, --debug integer      Enable debugging
-     -r, --resume             Connect, establish a session. Connect
-                              again and resume this session.
-     -s, --starttls           Connect, establish a plain session and
-                              start TLS when EOF or a SIGALRM is
-                              received.
-     --crlf                   Send CR LF instead of LF.
-     --x509fmtder             Use DER format for certificates to read
-                              from.
-     -f, --fingerprint        Send the openpgp fingerprint, instead
-                              of the key.
-     --disable-extensions     Disable all the TLS extensions.
-     --print-cert             Print the certificate in PEM format.
-     --recordsize integer     The maximum record size to advertize.
-     -V, --verbose            More verbose output.
-     --ciphers cipher1 cipher2...
-                              Ciphers to enable.
-     --protocols protocol1 protocol2...
-                              Protocols to enable.
-     --comp comp1 comp2...    Compression methods to enable.
-     --macs mac1 mac2...      MACs to enable.
-     --kx kx1 kx2...          Key exchange methods to enable.
-     --ctypes certType1 certType2...
-                              Certificate types to enable.
-     --priority PRIORITY STRING
-                              Priorities string.
-     --x509cafile FILE        Certificate file to use.
-     --x509crlfile FILE       CRL file to use.
-     --pgpkeyfile FILE        PGP Key file to use.
-     --pgpkeyring FILE        PGP Key ring file to use.
-     --pgpcertfile FILE       PGP Public Key (certificate) file to
-                              use.
-     --pgpsubkey HEX|auto     PGP subkey to use.
-     --x509keyfile FILE       X.509 key file to use.
-     --x509certfile FILE      X.509 Certificate file to use.
-     --srpusername NAME       SRP username to use.
-     --srppasswd PASSWD       SRP password to use.
-     --pskusername NAME       PSK username to use.
-     --pskkey KEY             PSK key (in hex) to use.
-     --opaque-prf-input DATA
-                              Use Opaque PRF Input DATA.
-     -p, --port PORT          The port to connect to.
-     --insecure               Don't abort program if server
-                              certificate can't be validated.
-     -l, --list               Print a list of the supported
-                              algorithms and modes.
-     -h, --help               prints this help
-     -v, --version            prints the program's version number
address@hidden example
-
address@hidden Example client PSK connection
address@hidden PSK client
-
-To connect to a server using PSK authentication, you need to enable
-the choice of PSK by using a cipher priority parameter such as in the
-example below.
-
address@hidden
-$ ./gnutls-cli -p 5556 localhost --pskusername psk_identity \
-  --pskkey 88f3824b3e5659f52d00e959bacab954b6540344 \
-  --priority NORMAL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK
-Resolving 'localhost'...
-Connecting to '127.0.0.1:5556'...
-- PSK authentication.
-- Version: TLS1.1
-- Key Exchange: PSK
-- Cipher: AES-128-CBC
-- MAC: SHA1
-- Compression: NULL
-- Handshake was completed
-
-- Simple Client Mode:
address@hidden example
-
-By keeping the @code{--pskusername} parameter and removing the
address@hidden parameter, it will query only for the password during
-the handshake.
-
address@hidden Listing the ciphersuites in a priority string
address@hidden Priority strings
-
address@hidden
-$ ./gnutls-cli --priority SECURE192 -l
-Cipher suites for SECURE192
-TLS_ECDHE_ECDSA_AES_256_CBC_SHA384                0xc0, 0x24   TLS1.2
-TLS_ECDHE_ECDSA_AES_256_GCM_SHA384                0xc0, 0x2e   TLS1.2
-TLS_ECDHE_RSA_AES_256_GCM_SHA384                  0xc0, 0x30   TLS1.2
-TLS_DHE_RSA_AES_256_CBC_SHA256                    0x00, 0x6b   TLS1.2
-TLS_DHE_DSS_AES_256_CBC_SHA256                    0x00, 0x6a   TLS1.2
-TLS_RSA_AES_256_CBC_SHA256                        0x00, 0x3d   TLS1.2
-
-Certificate types: CTYPE-X.509
-Protocols: VERS-TLS1.2, VERS-TLS1.1, VERS-TLS1.0, VERS-SSL3.0, VERS-DTLS1.0
-Compression: COMP-NULL
-Elliptic curves: CURVE-SECP384R1, CURVE-SECP521R1
-PK-signatures: SIGN-RSA-SHA384, SIGN-ECDSA-SHA384, SIGN-RSA-SHA512, 
SIGN-ECDSA-SHA512
address@hidden example
-
-
address@hidden The gnutls-serv tool
address@hidden The gnutls-serv tool
address@hidden gnutls-serv
-
-Simple server program that listens to incoming TLS connections.
-
address@hidden
-GnuTLS test server
-Usage: gnutls-serv [options]
-
-     -d, --debug integer      Enable debugging
-     -g, --generate           Generate Diffie-Hellman Parameters.
-     -p, --port integer       The port to connect to.
-     -q, --quiet              Suppress some messages.
-     --nodb                   Does not use the resume database.
-     --http                   Act as an HTTP Server.
-     --echo                   Act as an Echo Server.
-     --dhparams FILE          DH params file to use.
-     --x509fmtder             Use DER format for certificates
-     --x509cafile FILE        Certificate file to use.
-     --x509crlfile FILE       CRL file to use.
-     --pgpkeyring FILE        PGP Key ring file to use.
-     --pgpkeyfile FILE        PGP Key file to use.
-     --pgpcertfile FILE       PGP Public Key (certificate) file to
-                              use.
-     --pgpsubkey HEX|auto     PGP subkey to use.
-     --x509keyfile FILE       X.509 key file to use.
-     --x509certfile FILE      X.509 Certificate file to use.
-     --x509dsakeyfile FILE    Alternative X.509 key file to use.
-     --x509dsacertfile FILE   Alternative X.509 certificate file to
-                              use.
-     -r, --require-cert       Require a valid certificate.
-     -a, --disable-client-cert
-                              Disable request for a client
-                              certificate.
-     --pskpasswd FILE         PSK password file to use.
-     --pskhint HINT           PSK identity hint to use.
-     --srppasswd FILE         SRP password file to use.
-     --srppasswdconf FILE     SRP password conf file to use.
-     --opaque-prf-input DATA
-                              Use Opaque PRF Input DATA.
-     --ciphers cipher1 cipher2...
-                              Ciphers to enable.
-     --protocols protocol1 protocol2...
-                              Protocols to enable.
-     --comp comp1 comp2...    Compression methods to enable.
-     --macs mac1 mac2...      MACs to enable.
-     --kx kx1 kx2...          Key exchange methods to enable.
-     --ctypes certType1 certType2...
-                              Certificate types to enable.
-     --priority PRIORITY STRING
-                              Priorities string.
-     -l, --list               Print a list of the supported
-                              algorithms  and modes.
-     -h, --help               prints this help
-     -v, --version            prints the program's version number
address@hidden example
-
address@hidden Setting up a test HTTPS server
address@hidden HTTPS server
address@hidden debug server
-
-Running your own TLS server based on GnuTLS can be useful when
-debugging clients and/or GnuTLS itself.  This section describes how to
-use @code{gnutls-serv} as a simple HTTPS server.
-
-The most basic server can be started as:
-
address@hidden
-gnutls-serv --http
address@hidden example
-
-It will only support anonymous ciphersuites, which many TLS clients
-refuse to use.
-
-The next step is to add support for X.509.  First we generate a CA:
-
address@hidden
-$ certtool --generate-privkey > x509-ca-key.pem
-$ echo 'cn = GnuTLS test CA' > ca.tmpl
-$ echo 'ca' >> ca.tmpl
-$ echo 'cert_signing_key' >> ca.tmpl
-$ certtool --generate-self-signed --load-privkey x509-ca-key.pem \
-  --template ca.tmpl --outfile x509-ca.pem
-...
address@hidden example
-
-Then generate a server certificate.  Remember to change the dns_name
-value to the name of your server host, or skip that command to avoid
-the field.
-
address@hidden
-$ certtool --generate-privkey > x509-server-key.pem
-$ echo 'organization = GnuTLS test server' > server.tmpl
-$ echo 'cn = test.gnutls.org' >> server.tmpl
-$ echo 'tls_www_server' >> server.tmpl
-$ echo 'encryption_key' >> server.tmpl
-$ echo 'signing_key' >> server.tmpl
-$ echo 'dns_name = test.gnutls.org' >> server.tmpl
-$ certtool --generate-certificate --load-privkey x509-server-key.pem \
-  --load-ca-certificate x509-ca.pem --load-ca-privkey x509-ca-key.pem \
-  --template server.tmpl --outfile x509-server.pem
-...
address@hidden example
-
-For use in the client, you may want to generate a client certificate
-as well.
-
address@hidden
-$ certtool --generate-privkey > x509-client-key.pem
-$ echo 'cn = GnuTLS test client' > client.tmpl
-$ echo 'tls_www_client' >> client.tmpl
-$ echo 'encryption_key' >> client.tmpl
-$ echo 'signing_key' >> client.tmpl
-$ certtool --generate-certificate --load-privkey x509-client-key.pem \
-  --load-ca-certificate x509-ca.pem --load-ca-privkey x509-ca-key.pem \
-  --template client.tmpl --outfile x509-client.pem
-...
address@hidden example
-
-To be able to import the client key/certificate into some
-applications, you will need to convert them into a PKCS#12 structure.
-This also encrypts the security sensitive key with a password.
-
address@hidden
-$ certtool --to-p12 --load-ca-certificate x509-ca.pem \
-  --load-privkey x509-client-key.pem --load-certificate x509-client.pem \
-  --outder --outfile x509-client.p12
address@hidden example
-
-For icing, we'll create a proxy certificate for the client too.
-
address@hidden
-$ certtool --generate-privkey > x509-proxy-key.pem
-$ echo 'cn = GnuTLS test client proxy' > proxy.tmpl
-$ certtool --generate-proxy --load-privkey x509-proxy-key.pem \
-  --load-ca-certificate x509-client.pem --load-ca-privkey x509-client-key.pem \
-  --load-certificate x509-client.pem --template proxy.tmpl \
-  --outfile x509-proxy.pem
-...
address@hidden example
-
-Then start the server again:
-
address@hidden
-$ gnutls-serv --http \
-            --x509cafile x509-ca.pem \
-            --x509keyfile x509-server-key.pem \
-            --x509certfile x509-server.pem
address@hidden example
-
-Try connecting to the server using your web browser.  Note that the
-server listens to port 5556 by default.
-
-While you are at it, to allow connections using DSA, you can also
-create a DSA key and certificate for the server.  These credentials
-will be used in the final example below.
-
address@hidden
-$ certtool --generate-privkey --dsa > x509-server-key-dsa.pem
-$ certtool --generate-certificate --load-privkey x509-server-key-dsa.pem \
-  --load-ca-certificate x509-ca.pem --load-ca-privkey x509-ca-key.pem \
-  --template server.tmpl --outfile x509-server-dsa.pem
-...
address@hidden example
-
-The next step is to create OpenPGP credentials for the server.
-
address@hidden
-gpg --gen-key
-...enter whatever details you want, use 'test.gnutls.org' as name...
address@hidden example
-
-Make a note of the OpenPGP key identifier of the newly generated key,
-here it was @code{5D1D14D8}.  You will need to export the key for
-GnuTLS to be able to use it.
-
address@hidden
-gpg -a --export 5D1D14D8 > openpgp-server.txt
-gpg --export 5D1D14D8 > openpgp-server.bin
-gpg --export-secret-keys 5D1D14D8 > openpgp-server-key.bin
-gpg -a --export-secret-keys 5D1D14D8 > openpgp-server-key.txt
address@hidden example
-
-Let's start the server with support for OpenPGP credentials:
-
address@hidden
-gnutls-serv --http \
-            --pgpkeyfile openpgp-server-key.txt \
-            --pgpcertfile openpgp-server.txt
address@hidden example
-
-The next step is to add support for SRP authentication. This requires
-an SRP password file (see @ref{Invoking srptool}).
-To start the server with SRP support:
-
address@hidden
-gnutls-serv --http \
-            --srppasswdconf srp-tpasswd.conf \
-            --srppasswd srp-passwd.txt
address@hidden example
-
-Let's also start a server with support for PSK. This would require
-a password file created with @code{psktool} (see @ref{Invoking psktool}).
-
address@hidden
-gnutls-serv --http \
-            --pskpasswd psk-passwd.txt
address@hidden example
-
-Finally, we start the server with all the earlier parameters and you
-get this command:
-
address@hidden
-gnutls-serv --http \
-            --x509cafile x509-ca.pem \
-            --x509keyfile x509-server-key.pem \
-            --x509certfile x509-server.pem \
-            --x509dsakeyfile x509-server-key-dsa.pem \
-            --x509dsacertfile x509-server-dsa.pem \
-            --pgpkeyfile openpgp-server-key.txt \
-            --pgpcertfile openpgp-server.txt \
-            --srppasswdconf srp-tpasswd.conf \
-            --srppasswd srp-passwd.txt \
-            --pskpasswd psk-passwd.txt
address@hidden example
-
-
address@hidden The gnutls-cli-debug tool
address@hidden The gnutls-cli-debug tool
address@hidden gnutls-cli-debug
-
-This program was created to assist in debugging @acronym{GnuTLS}, but
-it might be useful to extract a @acronym{TLS} server's capabilities.
-It's purpose is to connect onto a @acronym{TLS} server, perform some
-tests and print the server's capabilities. If called with the `-v'
-parameter more checks will be performed. An example output is:
-
address@hidden
-crystal:/cvs/gnutls/src$ ./gnutls-cli-debug localhost -p 5556
-Resolving 'localhost'...
-Connecting to '127.0.0.1:5556'...
-Checking for TLS 1.1 support... yes
-Checking fallback from TLS 1.1 to... N/A
-Checking for TLS 1.0 support... yes
-Checking for SSL 3.0 support... yes
-Checking for version rollback bug in RSA PMS... no
-Checking for version rollback bug in Client Hello... no
-Checking whether we need to disable TLS 1.0... N/A
-Checking whether the server ignores the RSA PMS version... no
-Checking whether the server can accept Hello Extensions... yes
-Checking whether the server can accept cipher suites not in SSL 3.0 spec... yes
-Checking for certificate information... N/A
-Checking for trusted CAs... N/A
-Checking whether the server understands TLS closure alerts... yes
-Checking whether the server supports session resumption... yes
-Checking for export-grade ciphersuite support... no
-Checking RSA-export ciphersuite info... N/A
-Checking for anonymous authentication support... no
-Checking anonymous Diffie-Hellman group info... N/A
-Checking for ephemeral Diffie-Hellman support... no
-Checking ephemeral Diffie-Hellman group info... N/A
-Checking for AES cipher support (TLS extension)... yes
-Checking for 3DES cipher support... yes
-Checking for ARCFOUR 128 cipher support... yes
-Checking for ARCFOUR 40 cipher support... no
-Checking for MD5 MAC support... yes
-Checking for SHA1 MAC support... yes
-Checking for ZLIB compression support (TLS extension)... yes
-Checking for max record size (TLS extension)... yes
-Checking for SRP authentication support (TLS extension)... yes
-Checking for OpenPGP authentication support (TLS extension)... no
address@hidden example
-
address@hidden invoke-gnutls-cli.texi
address@hidden invoke-gnutls-serv.texi
address@hidden invoke-gnutls-cli-debug.texi
diff --git a/doc/cha-shared-key.texi b/doc/cha-shared-key.texi
index 28405aa..a8730f4 100644
--- a/doc/cha-shared-key.texi
+++ b/doc/cha-shared-key.texi
@@ -16,7 +16,7 @@ The rest of this chapter discusses details of these methods.
 
 @menu
 * Authentication using SRP::
-* Invoking srptool::
+* srptool Invocation::             Invoking srptool
 @end menu
 
 @node Authentication using SRP
@@ -67,53 +67,20 @@ authenticated using a certificate with RSA parameters.
 Helper functions are included in @acronym{GnuTLS}, used to generate and
 maintain @acronym{SRP} verifiers and password files.  A program to
 manipulate the required parameters for @acronym{SRP} authentication is
-also included.  See @ref{srptool}, for more information.
+also included.  See @ref{srptool Invocation}, for more information.
 
 @showfuncdesc{gnutls_srp_verifier}
 
 @showfuncB{gnutls_srp_base64_encode,gnutls_srp_base64_decode}
 
address@hidden Invoking srptool
address@hidden Invoking srptool
address@hidden
address@hidden srptool
-
-The @file{srptool} is a very simple program that emulates the programs
-in the @emph{Stanford SRP address@hidden
address@hidden://srp.stanford.edu/}.}. It requires two files,
-one called @code{tpasswd} which holds usernames and verifiers, 
-and @code{tpasswd.conf} which holds generators and primes.
-
-To create tpasswd.conf which holds the generator and prime values for
-the @acronym{SRP} protocol, run:
-
address@hidden
-$ srptool --create-conf /etc/tpasswd.conf
address@hidden example
-
-This command will create /etc/tpasswd and will add user 'test' (you
-will also be prompted for a password).  Verifiers are stored in a way that
-is compatible with libsrp.
-
address@hidden
-$ srptool --passwd /etc/tpasswd \
-    --passwd-conf /etc/tpasswd.conf -u test
address@hidden example
-
-This command will check against a password.  If the password matches
-the one in /etc/tpasswd you will get an ok.
-
address@hidden
-$ srptool --passwd /etc/tpasswd \
-    --passwd-conf /etc/tpasswd.conf --verify -u test
address@hidden example
address@hidden invoke-srptool.texi
 
 @node PSK authentication
 @section PSK authentication
 
 @menu
 * Authentication using PSK::
-* Invoking psktool::
+* psktool Invocation::             Invoking psktool
 @end menu
 
 @node Authentication using PSK
@@ -149,36 +116,7 @@ in @acronym{GnuTLS}.
 
 @showfuncC{gnutls_key_generate,gnutls_hex_encode,gnutls_hex_decode}
 
address@hidden Invoking psktool
address@hidden Invoking psktool
address@hidden psktool
-
-This is a program to manage @acronym{PSK} username and keys.
-It will generate random keys for the indicated username, 
-using a simple password file format.
-
address@hidden
-PSKtool help
-Usage : psktool [options]
-     -u, --username username
-                              specify username.
-     -p, --passwd FILE        specify a password file.
-     -s, --keysize SIZE       specify the key size in bytes.
-     -v, --version            prints the program's version number
-     -h, --help               shows this help text
address@hidden example
-
-The generation of a PSK password file is illustrated in the example below. 
-The password is provided in the prompt.
-
address@hidden
-$ ./psktool -u psk_identity -p psks.txt
-Generating a random key for user 'psk_identity'
-Key stored to psks.txt
-$ cat psks.txt
-psk_identity:88f3824b3e5659f52d00e959bacab954b6540344
-$
address@hidden example
address@hidden invoke-psktool.texi
 
 @node Anonymous authentication
 @section Anonymous authentication
diff --git a/doc/examples/ex-verify-ssh.c b/doc/examples/ex-verify-ssh.c
index c9fab66..c9a66b2 100644
--- a/doc/examples/ex-verify-ssh.c
+++ b/doc/examples/ex-verify-ssh.c
@@ -126,10 +126,11 @@ _ssh_verify_certificate_callback (gnutls_session_t 
session)
     }
   
   /* user trusts the key -> store it */
-  ret = gnutls_store_pubkey(NULL, NULL, hostname, "443", GNUTLS_CRT_X509, 
&cert_list[0], 0);
-  if (ret < 0)
+  if (ret != 0)
     {
-      fprintf(stderr, "gnutls_store_pubkey: %s\n", gnutls_strerror(ret));
+      ret = gnutls_store_pubkey(NULL, NULL, hostname, "443", GNUTLS_CRT_X509, 
&cert_list[0], 0);
+      if (ret < 0)
+        fprintf(stderr, "gnutls_store_pubkey: %s\n", gnutls_strerror(ret));
     }
 
   /* notify gnutls to continue handshake normally */
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
index f582008..26da978 100644
--- a/doc/manpages/Makefile.am
+++ b/doc/manpages/Makefile.am
@@ -26,29 +26,29 @@ if ENABLE_SRP
 dist_man_MANS += srptool.1
 endif
 
-certtool.1: ../../src/certtool-args.def.in
-       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl ../../src/certtool-args.def
+certtool.1: ../../src/certtool-args.def
+       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl $<
 
-ocsptool.1: ../../src/ocsptool-args.def.in
-       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl ../../src/ocsptool-args.def
+ocsptool.1: ../../src/ocsptool-args.def
+       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl $<
 
-gnutls-cli.1: ../../src/cli-args.def.in
-       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl ../../src/cli-args.def
+gnutls-cli.1: ../../src/cli-args.def
+       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl $<
 
-gnutls-serv.1: ../../src/serv-args.def.in
-       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl ../../src/serv-args.def
+gnutls-serv.1: ../../src/serv-args.def
+       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl $<
 
-gnutls-cli-debug.1: ../../src/cli-debug-args.def.in
-       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl ../../src/cli-debug-args.def
+gnutls-cli-debug.1: ../../src/cli-debug-args.def
+       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl $<
 
-srptool.1: ../../src/srptool-args.def.in
-       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl ../../src/srptool-args.def
+srptool.1: ../../src/srptool-args.def
+       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl $<
 
-p11tool.1: ../../src/p11tool-args.def.in
-       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl ../../src/p11tool-args.def
+p11tool.1: ../../src/p11tool-args.def
+       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl $<
 
-psktool.1: ../../src/psk-args.def.in
-       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl ../../src/psk-args.def
+psktool.1: ../../src/psk-args.def
+       -autogen -DMAN_SECTION=1 -Tagman-cmd.tpl $<
 
 APIMANS =
 APIMANS += gnutls_pubkey_init.3
diff --git a/lib/auth/cert.h b/lib/auth/cert.h
index b0931fb..55ff0bd 100644
--- a/lib/auth/cert.h
+++ b/lib/auth/cert.h
@@ -24,8 +24,8 @@
 #define AUTH_CERT_H
 #include "gnutls_auth.h"
 #include <auth/dh_common.h>
-#include "x509/x509_int.h"
-#include "openpgp/openpgp_int.h"
+#include <x509/x509_int.h>
+#include <openpgp/openpgp_int.h>
 #include <gnutls/abstract.h>
 #include <gnutls/compat.h>
 #include <gnutls_str_array.h>
diff --git a/lib/includes/gnutls/ocsp.h b/lib/includes/gnutls/ocsp.h
index 89eb673..f2703c0 100644
--- a/lib/includes/gnutls/ocsp.h
+++ b/lib/includes/gnutls/ocsp.h
@@ -220,11 +220,11 @@ extern "C"
                                   gnutls_datum_t *issuer_name_hash,
                                   gnutls_datum_t *issuer_key_hash,
                                   gnutls_datum_t *serial_number,
-                                  int *cert_status,
+                                  unsigned int *cert_status,
                                   time_t *this_update,
                                   time_t *next_update,
                                   time_t *revocation_time,
-                                  int *revocation_reason);
+                                  unsigned int *revocation_reason);
   int gnutls_ocsp_resp_get_extension (gnutls_ocsp_resp_t resp,
                                      unsigned indx,
                                      gnutls_datum_t *oid,
@@ -243,11 +243,15 @@ extern "C"
   int gnutls_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp,
                                      gnutls_x509_crt_t signercert,
                                      unsigned *verify,
-                                     int flags);
+                                     unsigned int flags);
   int gnutls_ocsp_resp_verify (gnutls_ocsp_resp_t resp,
                               gnutls_x509_trust_list_t trustlist,
                               unsigned *verify,
-                              int flags);
+                              unsigned int flags);
+  int gnutls_ocsp_resp_verify_cred (gnutls_ocsp_resp_t resp,
+                        gnutls_certificate_credentials_t cred,
+                        unsigned *verify,
+                        unsigned int flags);
 
 #ifdef __cplusplus
 }
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 40765f8..98afb74 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -773,6 +773,7 @@ GNUTLS_3_0_0 {
        gnutls_priority_ecc_curve_list;
        gnutls_verify_stored_pubkey;
        gnutls_store_pubkey;
+       gnutls_ocsp_resp_verify_cred;
 } GNUTLS_2_12;
 
 GNUTLS_PRIVATE {
diff --git a/lib/openpgp/openpgp_int.h b/lib/openpgp/openpgp_int.h
index c412e1e..9f6b3a5 100644
--- a/lib/openpgp/openpgp_int.h
+++ b/lib/openpgp/openpgp_int.h
@@ -29,7 +29,7 @@
 
 #ifdef ENABLE_OPENPGP
 
-#include <opencdk.h>
+#include <opencdk/opencdk.h>
 #include <gnutls/openpgp.h>
 
 #define KEYID_IMPORT(dst, src) { \
diff --git a/lib/x509/ocsp.c b/lib/x509/ocsp.c
index 732a99e..cf9b08a 100644
--- a/lib/x509/ocsp.c
+++ b/lib/x509/ocsp.c
@@ -32,6 +32,7 @@
 #include "verify-high.h"
 
 #include <gnutls/ocsp.h>
+#include <auth/cert.h>
 
 typedef struct gnutls_ocsp_req_int
 {
@@ -1331,11 +1332,11 @@ gnutls_ocsp_resp_get_single (gnutls_ocsp_resp_t resp,
                             gnutls_datum_t *issuer_name_hash,
                             gnutls_datum_t *issuer_key_hash,
                             gnutls_datum_t *serial_number,
-                            int *cert_status,
+                            unsigned int *cert_status,
                             time_t *this_update,
                             time_t *next_update,
                             time_t *revocation_time,
-                            int *revocation_reason)
+                            unsigned int *revocation_reason)
 {
   gnutls_datum_t sa;
   char name[ASN1_MAX_NAME_SIZE];
@@ -1910,35 +1911,11 @@ find_signercert (gnutls_ocsp_resp_t resp)
   return signercert;
 }
 
-/**
- * gnutls_ocsp_resp_verify_direct:
- * @resp: should contain a #gnutls_ocsp_resp_t structure
- * @signercert: certificate believed to have signed the response
- * @verify: output variable with verification status, an 
#gnutls_ocsp_cert_status_t
- * @flags: verification flags, 0 for now.
- *
- * Verify signature of the Basic OCSP Response against the public key
- * in the @signercert certificate.
- *
- * The output @verify variable will hold verification status codes
- * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
- * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
- * function returned %GNUTLS_E_SUCCESS.
- *
- * Note that the function returns %GNUTLS_E_SUCCESS even when
- * verification failed.  The caller must always inspect the @verify
- * variable to find out the verification status.
- *
- * The @flags variable should be 0 for now.
- *
- * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
- *   negative error value.
- **/
-int
-gnutls_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp,
-                               gnutls_x509_crt_t signercert,
-                               unsigned *verify,
-                               int flags)
+static int
+_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp,
+                         gnutls_x509_crt_t signercert,
+                         unsigned int *verify,
+                         unsigned int flags)
 {
   gnutls_datum_t sig = { NULL };
   gnutls_datum_t data = { NULL };
@@ -1952,7 +1929,13 @@ gnutls_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  sigalg = gnutls_ocsp_resp_get_signature_algorithm (resp);
+  rc = gnutls_ocsp_resp_get_signature_algorithm (resp);
+  if (rc < 0)
+    {
+      gnutls_assert ();
+      goto done;
+    }
+  sigalg = rc;
 
   rc = export (resp->basicresp, "tbsResponseData", &data);
   if (rc != GNUTLS_E_SUCCESS)
@@ -2006,6 +1989,142 @@ gnutls_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp,
   return rc;
 }
 
+static inline unsigned int vstatus_to_ocsp_status(unsigned int status)
+{
+unsigned int ostatus;
+
+  if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
+    ostatus = GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM;
+  else if (status & GNUTLS_CERT_NOT_ACTIVATED)
+    ostatus = GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED;
+  else if (status & GNUTLS_CERT_EXPIRED)
+    ostatus = GNUTLS_OCSP_VERIFY_CERT_EXPIRED;
+  else
+    ostatus = GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER;
+
+  return ostatus;
+}
+
+static int check_ocsp_purpose(gnutls_x509_crt_t signercert)
+{
+char oidtmp[sizeof (GNUTLS_KP_OCSP_SIGNING)];
+size_t oidsize;
+int indx, rc;
+
+      for (indx = 0; ; indx++)
+       {
+         oidsize = sizeof (oidtmp);
+         rc = gnutls_x509_crt_get_key_purpose_oid (signercert, indx,
+                                                   oidtmp, &oidsize,
+                                                   NULL);
+         if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+           {
+             gnutls_assert();
+             return rc;
+           }
+         else if (rc == GNUTLS_E_SHORT_MEMORY_BUFFER)
+           {
+             gnutls_assert ();
+             continue;
+           }
+         else if (rc != GNUTLS_E_SUCCESS)
+           {
+             return gnutls_assert_val(rc);
+           }
+
+         if (memcmp (oidtmp, GNUTLS_KP_OCSP_SIGNING, oidsize) != 0)
+           {
+             gnutls_assert ();
+             continue;
+           }
+         break;
+       }
+  
+  return 0;
+}
+
+/**
+ * gnutls_ocsp_resp_verify_direct:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ * @issuer: certificate believed to have signed the response
+ * @verify: output variable with verification status, an 
#gnutls_ocsp_cert_status_t
+ * @flags: verification flags, 0 for now.
+ *
+ * Verify signature of the Basic OCSP Response against the public key
+ * in the @issuer certificate.
+ *
+ * The output @verify variable will hold verification status codes
+ * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
+ * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
+ * function returned %GNUTLS_E_SUCCESS.
+ *
+ * Note that the function returns %GNUTLS_E_SUCCESS even when
+ * verification failed.  The caller must always inspect the @verify
+ * variable to find out the verification status.
+ *
+ * The @flags variable should be 0 for now.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp,
+                               gnutls_x509_crt_t issuer,
+                               unsigned int *verify,
+                               unsigned int flags)
+{
+  gnutls_x509_crt_t signercert;
+  int rc;
+
+  if (resp == NULL || issuer == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  signercert = find_signercert (resp);
+  if (!signercert)
+    {
+      signercert = issuer;
+    }
+  else /* response contains a signer. Verify him */
+    {
+      unsigned int vtmp;
+
+      rc = gnutls_x509_crt_verify (signercert, &issuer, 1, 0, &vtmp);
+      if (rc != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         goto done;
+       }
+
+      if (vtmp != 0)
+        {
+          *verify = vstatus_to_ocsp_status(vtmp);
+         gnutls_assert ();
+         rc = GNUTLS_E_SUCCESS;
+         goto done;
+       }
+
+      rc = check_ocsp_purpose(signercert);
+      if (rc < 0)
+        {
+          gnutls_assert ();
+          *verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
+          rc = GNUTLS_E_SUCCESS;
+          goto done;
+        }
+    }
+
+  rc = _ocsp_resp_verify_direct(resp, signercert, verify, flags);
+  
+ done:
+  if (signercert != issuer)
+    gnutls_x509_crt_deinit(signercert);
+
+  return rc;
+}
+
 /**
  * gnutls_ocsp_resp_verify:
  * @resp: should contain a #gnutls_ocsp_resp_t structure
@@ -2039,8 +2158,8 @@ gnutls_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp,
 int
 gnutls_ocsp_resp_verify (gnutls_ocsp_resp_t resp,
                         gnutls_x509_trust_list_t trustlist,
-                        unsigned *verify,
-                        int flags)
+                        unsigned int *verify,
+                        unsigned int flags)
 {
   gnutls_x509_crt_t signercert = NULL;
   int rc;
@@ -2079,9 +2198,6 @@ gnutls_ocsp_resp_verify (gnutls_ocsp_resp_t resp,
       /* not in trustlist, need to verify signature and bits */
       gnutls_x509_crt_t issuer;
       unsigned vtmp;
-      char oidtmp[sizeof (GNUTLS_KP_OCSP_SIGNING)];
-      size_t oidsize;
-      int indx;
 
       gnutls_assert ();
 
@@ -2103,58 +2219,49 @@ gnutls_ocsp_resp_verify (gnutls_ocsp_resp_t resp,
        }
 
       if (vtmp != 0)
-       {
+        {
+          *verify = vstatus_to_ocsp_status(vtmp);
          gnutls_assert ();
-         if (vtmp & GNUTLS_CERT_INSECURE_ALGORITHM)
-           *verify = GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM;
-         else if (vtmp & GNUTLS_CERT_NOT_ACTIVATED)
-           *verify = GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED;
-         else if (vtmp & GNUTLS_CERT_EXPIRED)
-           *verify = GNUTLS_OCSP_VERIFY_CERT_EXPIRED;
-         else
-           *verify = GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER;
          rc = GNUTLS_E_SUCCESS;
          goto done;
        }
 
-      for (indx = 0; ; indx++)
-       {
-         oidsize = sizeof (oidtmp);
-         rc = gnutls_x509_crt_get_key_purpose_oid (signercert, indx,
-                                                   oidtmp, &oidsize,
-                                                   NULL);
-         if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
-           {
-             gnutls_assert ();
-             *verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
-             rc = GNUTLS_E_SUCCESS;
-             goto done;
-           }
-         else if (rc == GNUTLS_E_SHORT_MEMORY_BUFFER)
-           {
-             gnutls_assert ();
-             continue;
-           }
-         else if (rc != GNUTLS_E_SUCCESS)
-           {
-             gnutls_assert ();
-             goto done;
-           }
-
-         if (memcmp (oidtmp, GNUTLS_KP_OCSP_SIGNING, oidsize) != 0)
-           {
-             gnutls_assert ();
-             continue;
-           }
-
-         break;
-       }
+      rc = check_ocsp_purpose(signercert);
+      if (rc < 0)
+        {
+          gnutls_assert ();
+          *verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
+          rc = GNUTLS_E_SUCCESS;
+          goto done;
+        }
     }
 
-  rc = gnutls_ocsp_resp_verify_direct (resp, signercert, verify, flags);
+  rc = _ocsp_resp_verify_direct (resp, signercert, verify, flags);
 
  done:
   gnutls_x509_crt_deinit (signercert);
 
   return rc;
 }
+
+/**
+ * gnutls_ocsp_resp_verify_cred:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ * @trustlist: the certificate credentials structure
+ * @verify: output variable with verification status, an 
#gnutls_ocsp_cert_status_t
+ * @flags: verification flags, 0 for now.
+ *
+ * This function is identical to gnutls_ocsp_resp_verify() but would
+ * use the trusted anchors from the certificate credentials structure.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_ocsp_resp_verify_cred (gnutls_ocsp_resp_t resp,
+                        gnutls_certificate_credentials_t cred,
+                        unsigned int*verify,
+                        unsigned int flags)
+{
+  return gnutls_ocsp_resp_verify( resp, cred->tlist, verify, flags);
+}
diff --git a/lib/x509/ocsp_output.c b/lib/x509/ocsp_output.c
index 0a0601f..737b227 100644
--- a/lib/x509/ocsp_output.c
+++ b/lib/x509/ocsp_output.c
@@ -321,11 +321,11 @@ print_resp (gnutls_buffer_st * str, gnutls_ocsp_resp_t 
resp,
     {
       gnutls_digest_algorithm_t digest;
       gnutls_datum_t in, ik, sn;
-      int cert_status;
+      unsigned int cert_status;
       time_t this_update;
       time_t next_update;
       time_t revocation_time;
-      int revocation_reason;
+      unsigned int revocation_reason;
 
       ret = gnutls_ocsp_resp_get_single (resp,
                                         indx,
diff --git a/src/Makefile.am b/src/Makefile.am
index 136484d..72d3e6a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -73,7 +73,7 @@ libcmd_srp_la_SOURCES = srptool-args.def srptool-args.c 
srptool-args.h
 endif
 
 if ENABLE_OCSP
-ocsptool_SOURCES = ocsptool.c ocsptool-common.h \
+ocsptool_SOURCES = ocsptool.c ocsptool-common.h ocsptool-common.c \
        socket.c socket.h
 ocsptool_LDADD = ../lib/libgnutls.la libcmd-ocsp.la ../gl/libgnu.la 
$(LIBOPTS_LDADD)
 noinst_LTLIBRARIES += libcmd-ocsp.la
@@ -90,7 +90,7 @@ libcmd_psk_la_SOURCES = psk-args.def psk-args.c psk-args.h
 BENCHMARK_SRCS = benchmark-cipher.c benchmark.c benchmark.h benchmark-tls.c
 
 gnutls_cli_SOURCES = cli.c common.h common.c \
-       socket.c socket.h \
+       socket.c socket.h ocsptool-common.c \
        $(PKCS11_SRCS) $(BENCHMARK_SRCS)
 gnutls_cli_LDADD = ../lib/libgnutls.la
 gnutls_cli_LDADD += libcmd-cli.la ../gl/libgnu.la $(LIBOPTS_LDADD)
@@ -139,19 +139,19 @@ libcmd_p11tool_la_LIBADD += ../gl/libgnu.la 
$(INET_PTON_LIB)
 
 endif # ENABLE_PKCS11
 
-ocsptool-args.c: $(srcdir)/ocsptool-args.def.in
+ocsptool-args.c: $(srcdir)/ocsptool-args.def
        -autogen ocsptool-args.def
-p11tool-args.c: $(srcdir)/p11tool-args.def.in
+p11tool-args.c: $(srcdir)/p11tool-args.def
        -autogen p11tool-args.def
-psk-args.c: $(srcdir)/psk-args.def.in
+psk-args.c: $(srcdir)/psk-args.def
        -autogen psk-args.def
-cli-debug-args.c: $(srcdir)/cli-debug-args.def.in
+cli-debug-args.c: $(srcdir)/cli-debug-args.def
        -autogen cli-debug-args.def
-cli-args.c: $(srcdir)/cli-args.def.in
+cli-args.c: $(srcdir)/cli-args.def
        -autogen cli-args.def
-serv-args.c: $(srcdir)/serv-args.def.in
+serv-args.c: $(srcdir)/serv-args.def
        -autogen serv-args.def
-srptool-args.c: $(srcdir)/srptool-args.def.in
+srptool-args.c: $(srcdir)/srptool-args.def
        -autogen srptool-args.def
-certtool-args.c: $(srcdir)/certtool-args.def.in
+certtool-args.c: $(srcdir)/certtool-args.def
        -autogen certtool-args.def
diff --git a/src/certtool-args.def.in b/src/certtool-args.def.in
index acf516a..74a73c3 100644
--- a/src/certtool-args.def.in
+++ b/src/certtool-args.def.in
@@ -2,7 +2,9 @@ AutoGen Definitions options;
 prog-name     = certtool;
 prog-title    = "GnuTLS PKCS #11 tool";
 prog-desc     = "Manipulate certificates and private keys.";
-detail    = "Tool to parse and generate X.509 certificates, requests and 
private keys.";
+detail    = "Tool to parse and generate X.509 certificates, requests and 
private keys.
+It can be used interactively or non interactively by
+specifying the template command line option.";
 help-value = "h";
 short-usage   = "certtool [options] [url]\ncerttool --help for usage 
instructions.\n";
 prog-group    = "GnuTLS";
@@ -382,7 +384,7 @@ flag = {
 
 doc-section = {
   ds-type = 'SEE ALSO';
-  ds-format = 'man';
+  ds-format = 'texi';
   ds-text   = <<-_EOT_
     p11tool (1)
 _EOT_;
@@ -392,11 +394,16 @@ doc-section = {
   ds-type = 'EXAMPLES';
   ds-format = 'texi';
   ds-text   = <<-_EOT_
-To create a private key, run:
address@hidden Generating private keys
+To create an RSA private key, run:
 @example
-$ certtool --generate-privkey --outfile key.pem
+$ certtool --generate-privkey --outfile key.pem --rsa
 @end example
 
+To create a DSA or elliptic curves (ECDSA) private key use the
+above command combined with 'dsa' or 'ecc' options.
+
address@hidden Generating certificate requests
 To create a certificate request (needed when the certificate is  issued  by
 another party), run:
 @example
@@ -404,12 +411,26 @@ certtool --generate-request --load-privkey key.pem \
    --outfile request.pem
 @end example
 
-To create a certificate request using a key stored in a PKCS #11 token, run:
+If the private key is stored in a smart card you can generate
+a request by specifying the private key object URL.
 @example
 $ ./certtool --generate-request --load-privkey "pkcs11:..." \
   --load-pubkey "pkcs11:..." --outfile request.pem
 @end example
 
+
address@hidden Generating a self-signed certificate
+To create a self signed certificate, use the command:
address@hidden
+$ certtool --generate-privkey --outfile ca-key.pem
+$ certtool --generate-self-signed --load-privkey ca-key.pem \
+   --outfile ca-cert.pem
address@hidden example
+
+Note that a self-signed certificate usually belongs to a certificate
+authority, that signs other certificates.
+
address@hidden Generating a certificate
 To generate a certificate using the previous request, use the command:
 @example
 $ certtool --generate-certificate --load-request request.pem \
@@ -424,11 +445,13 @@ $ certtool --generate-certificate --load-privkey key.pem \
    --load-ca-privkey ca-key.pem
 @end example
 
address@hidden Certificate information
 To view the certificate information, use:
 @example
 $ certtool --certificate-info --infile cert.pem
 @end example
 
address@hidden PKCS #12 structure generation
 To generate a PKCS #12 structure using the previous key and certificate,
 use the command:
 @example
@@ -436,6 +459,204 @@ $ certtool --load-certificate cert.pem --load-privkey 
key.pem \
    --to-p12 --outder --outfile key.p12
 @end example
 
+Some tools (reportedly web browsers) have problems with that file
+because it does not contain the CA certificate for the certificate.
+To work around that problem in the tool, you can use the
+--load-ca-certificate parameter as follows:
+
address@hidden
+$ certtool --load-ca-certificate ca.pem \
+  --load-certificate cert.pem --load-privkey key.pem \
+  --to-p12 --outder --outfile key.p12
address@hidden example
+
address@hidden Diffie-Hellman parameter generation
+To generate parameters for Diffie-Hellman key exchange, use the command:
address@hidden
+$ certtool --generate-dh-params --outfile dh.pem --sec-param normal
address@hidden example
+
address@hidden Proxy certificate generation
+Proxy certificate can be used to delegate your credential to a
+temporary, typically short-lived, certificate.  To create one from the
+previously created certificate, first create a temporary key and then
+generate a proxy certificate for it, using the commands:
+
address@hidden
+$ certtool --generate-privkey > proxy-key.pem
+$ certtool --generate-proxy --load-ca-privkey key.pem \
+  --load-privkey proxy-key.pem --load-certificate cert.pem \
+  --outfile proxy-cert.pem
address@hidden example
+
address@hidden Certificate revocation list generation
+To create an empty Certificate Revocation List (CRL) do:
+
address@hidden
+$ certtool --generate-crl --load-ca-privkey x509-ca-key.pem \
+           --load-ca-certificate x509-ca.pem
address@hidden example
+
+To create a CRL that contains some revoked certificates, place the
+certificates in a file and use @code{--load-certificate} as follows:
+
address@hidden
+$ certtool --generate-crl --load-ca-privkey x509-ca-key.pem \
+  --load-ca-certificate x509-ca.pem --load-certificate revoked-certs.pem
address@hidden example
+
+To verify a Certificate Revocation List (CRL) do:
+
address@hidden
+$ certtool --verify-crl --load-ca-certificate x509-ca.pem < crl.pem
address@hidden example
+_EOT_;
+};
+
+
+doc-section = {
+  ds-type = 'FILES';
+  ds-format = 'texi';
+  ds-text   = <<-_EOT_
address@hidden Certtool's template file format
+A template file can be used to avoid the interactive questions of
+certtool. Initially create a file named 'cert.cfg' that contains the 
information
+about the certificate. The template can be used as below:
+
address@hidden
+$ certtool --generate-certificate cert.pem --load-privkey key.pem  \
+   --template cert.cfg \
+   --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem
address@hidden example
+
+An example certtool template file that can be used to generate a certificate
+request or a self signed certificate follows.
+
address@hidden
+# X.509 Certificate options
+#
+# DN options
+
+# The organization of the subject.
+organization = "Koko inc."
+
+# The organizational unit of the subject.
+unit = "sleeping dept."
+
+# The locality of the subject.
+# locality =
+
+# The state of the certificate owner.
+state = "Attiki"
+
+# The country of the subject. Two letter code.
+country = GR
+
+# The common name of the certificate owner.
+cn = "Cindy Lauper"
+
+# A user id of the certificate owner.
+#uid = "clauper"
+
+# If the supported DN OIDs are not adequate you can set
+# any OID here.
+# For example set the X.520 Title and the X.520 Pseudonym
+# by using OID and string pairs.
+#dn_oid = 2.5.4.12 Dr. 
+#dn_oid = 2.5.4.65 jackal
+
+# This is deprecated and should not be used in new
+# certificates.
+# pkcs9_email = "none@@none.org"
+
+# The serial number of the certificate
+serial = 007
+
+# In how many days, counting from today, this certificate will expire.
+expiration_days = 700
+
+# X.509 v3 extensions
+
+# A dnsname in case of a WWW server.
+#dns_name = "www.none.org"
+#dns_name = "www.morethanone.org"
+
+# An IP address in case of a server.
+#ip_address = "192.168.1.1"
+
+# An email in case of a person
+email = "none@@none.org"
+
+# Challenge password used in certificate requests
+challenge_passwd = 123456
+
+# key_purpose_oid = 1.2.3.4.5.6.7
+# key_purpose_oid = 1.2.3.4.5.6.7.9
+
+# An URL that has CRLs (certificate revocation lists)
+# available. Needed in CA certificates.
+#crl_dist_points = "http://www.getcrl.crl/getcrl/";
+
+# Whether this is a CA certificate or not
+#ca
+
+# Whether this certificate will be used for a TLS client
+#tls_www_client
+
+# Whether this certificate will be used for a TLS server
+#tls_www_server
+
+# Whether this certificate will be used to sign data (needed
+# in TLS DHE ciphersuites).
+signing_key
+
+# Whether this certificate will be used to encrypt data (needed
+# in TLS RSA ciphersuites). Note that it is preferred to use different
+# keys for encryption and signing.
+#encryption_key
+
+# Whether this key will be used to sign other certificates.
+#cert_signing_key
+
+# Whether this key will be used to sign CRLs.
+#crl_signing_key
+
+# Whether this key will be used to sign code.
+#code_signing_key
+
+# Whether this key will be used to sign OCSP data.
+#ocsp_signing_key
+
+# Whether this key will be used for time stamping.
+#time_stamping_key
+
+# Whether this key will be used for IPsec IKE operations.
+#ipsec_ike_key
+
+# When generating a certificate from a certificate
+# request, then honor the extensions stored in the request
+# and store them in the real certificate.
+#honor_crq_extensions
+
+# Path length contraint. Sets the maximum number of
+# certificates that can be used to certify this certificate.
+# (i.e. the certificate chain length)
+#path_len = -1
+#path_len = 2
+
+# Options for proxy certificates
+# proxy_policy_language = 1.3.6.1.5.5.7.21.1
+
+# Options for generating a CRL
+
+# next CRL update will be in 43 days (wow)
+#crl_next_update = 43
+
+# this is the 5th CRL by this CA
+#crl_number = 5
+
address@hidden example
+
 _EOT_;
 };
 
diff --git a/src/cli-args.def.in b/src/cli-args.def.in
index 92c3bd6..afe2926 100644
--- a/src/cli-args.def.in
+++ b/src/cli-args.def.in
@@ -39,10 +39,20 @@ flag = {
 flag = {
     name      = ssh;
     descrip   = "Enable SSH-style authentication";
+    disabled;
+    disable   = "no";
     doc       = "This option will, in addition to certificate authentication, 
perform authentication based on stored public keys.";
 };
 
 flag = {
+    name      = ocsp;
+    descrip   = "Enable OCSP certificate verification";
+    disabled;
+    disable   = "no";
+    doc       = "This option will enable verification of the peer's 
certificate using ocsp";
+};
+
+flag = {
     name      = resume;
     value     = r;
     descrip   = "Connect, establish a session. Connect again and resume this 
session";
@@ -313,6 +323,12 @@ TLS_ECDHE_RSA_AES_256_GCM_SHA384                  0xc0, 
0x30       TLS1.2
 TLS_DHE_RSA_AES_256_CBC_SHA256                    0x00, 0x6b   TLS1.2
 TLS_DHE_DSS_AES_256_CBC_SHA256                    0x00, 0x6a   TLS1.2
 TLS_RSA_AES_256_CBC_SHA256                        0x00, 0x3d   TLS1.2
+
+Certificate types: CTYPE-X.509
+Protocols: VERS-TLS1.2, VERS-TLS1.1, VERS-TLS1.0, VERS-SSL3.0, VERS-DTLS1.0
+Compression: COMP-NULL
+Elliptic curves: CURVE-SECP384R1, CURVE-SECP521R1
+PK-signatures: SIGN-RSA-SHA384, SIGN-ECDSA-SHA384, SIGN-RSA-SHA512, 
SIGN-ECDSA-SHA512
 @end example
 _EOF_;
 };
diff --git a/src/cli-debug-args.def.in b/src/cli-debug-args.def.in
index 1aa6b7a..e07fd48 100644
--- a/src/cli-debug-args.def.in
+++ b/src/cli-debug-args.def.in
@@ -7,8 +7,11 @@ short-usage   = "Usage: gnutls-cli-debug [options] 
hostname\ngnutls-cli --help f
 prog-group    = "GnuTLS";
 explain       = "";
 detail        = "TLS debug client. It sets up multiple TLS connections to 
-a server and queries its capabilities. Can be used to check for servers with
-special needs or bugs.";
+a server and queries its capabilities. It was created to assist in debugging 
+GnuTLS, but it might be useful to extract a TLS server's capabilities.
+It connects to a TLS server, performs tests and print the server's 
+capabilities. If called with the `-v' parameter more checks will be performed.
+Can be used to check for servers with special needs or bugs.";
 gnu-usage;
 no-xlate = opt;
 no-misuse-usage;
@@ -62,3 +65,57 @@ gnutls-cli(1), gnutls-serv(1)
 _EOText_;
 };
 
+doc-section = {
+  ds-type = 'EXAMPLES';
+  ds-format = 'texi';
+  ds-text   = <<-_EOF_
address@hidden
+$ ../src/gnutls-cli-debug localhost
+Resolving 'localhost'...
+Connecting to '127.0.0.1:443'...
+Checking for SSL 3.0 support... yes
+Checking whether %COMPAT is required... no
+Checking for TLS 1.0 support... yes
+Checking for TLS 1.1 support... no
+Checking fallback from TLS 1.1 to... TLS 1.0
+Checking for TLS 1.2 support... no
+Checking whether we need to disable TLS 1.0... N/A
+Checking for Safe renegotiation support... yes
+Checking for Safe renegotiation support (SCSV)... yes
+Checking for HTTPS server name... not checked
+Checking for version rollback bug in RSA PMS... no
+Checking for version rollback bug in Client Hello... no
+Checking whether the server ignores the RSA PMS version... no
+Checking whether the server can accept Hello Extensions... yes
+Checking whether the server can accept small records (512 bytes)... yes
+Checking whether the server can accept cipher suites not in SSL 3.0 spec... yes
+Checking whether the server can accept a bogus TLS record version in the 
client hello... yes
+Checking for certificate information... N/A
+Checking for trusted CAs... N/A
+Checking whether the server understands TLS closure alerts... partially
+Checking whether the server supports session resumption... yes
+Checking for export-grade ciphersuite support... no
+Checking RSA-export ciphersuite info... N/A
+Checking for anonymous authentication support... no
+Checking anonymous Diffie-Hellman group info... N/A
+Checking for ephemeral Diffie-Hellman support... no
+Checking ephemeral Diffie-Hellman group info... N/A
+Checking for ephemeral EC Diffie-Hellman support... yes
+Checking ephemeral EC Diffie-Hellman group info...
+ Curve SECP256R1 
+Checking for AES-GCM cipher support... no
+Checking for AES-CBC cipher support... yes
+Checking for CAMELLIA cipher support... no
+Checking for 3DES-CBC cipher support... yes
+Checking for ARCFOUR 128 cipher support... yes
+Checking for ARCFOUR 40 cipher support... no
+Checking for MD5 MAC support... yes
+Checking for SHA1 MAC support... yes
+Checking for SHA256 MAC support... no
+Checking for ZLIB compression support... no
+Checking for max record size... no
+Checking for OpenPGP authentication support... no
address@hidden example
+_EOF_;
+};
+
diff --git a/src/cli.c b/src/cli.c
index 4226e77..bfe9851 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -57,6 +57,7 @@
 
 #include <gettext.h>
 #include <cli-args.h>
+#include <ocsptool-common.h>
 
 #define MAX_BUF 4096
 
@@ -68,7 +69,7 @@ int record_max_size;
 int fingerprint;
 int crlf;
 unsigned int verbose = 0;
-extern int print_cert;
+int print_cert;
 
 #define DEFAULT_CA_FILE "/etc/ssl/certs/ca-certificates.crt"
 
@@ -100,6 +101,7 @@ static gnutls_certificate_credentials_t xcred;
 static void check_rehandshake (socket_st * socket, int ret);
 static int do_handshake (socket_st * socket);
 static void init_global_tls_stuff (void);
+static int cert_verify_ocsp (gnutls_session_t session);
 
 /* Helper functions to load a certificate and key
  * files into memory.
@@ -449,7 +451,7 @@ cert_verify_callback (gnutls_session_t session)
 {
   int rc;
   unsigned int status = 0;
-  int ssh = HAVE_OPT(SSH);
+  int ssh = ENABLED_OPT(SSH);
 
   if (!x509_cafile && !pgp_keyring)
     return 0;
@@ -461,6 +463,18 @@ cert_verify_callback (gnutls_session_t session)
       if (!insecure && !ssh)
         return -1;
     }
+  else if (ENABLED_OPT(OCSP))
+    { /* off-line verification succeeded. Try OCSP */
+      rc = cert_verify_ocsp(session);
+      if (rc == 0)
+        {
+          printf ("*** Verifying (with OCSP) server certificate failed...\n");
+          if (!insecure && !ssh)
+            return -1;
+        }
+      else if (rc == -1)
+        printf("*** OCSP response ignored\n");
+    }
 
   if (ssh) /* try ssh auth */
     {
@@ -478,7 +492,7 @@ cert_verify_callback (gnutls_session_t session)
                                        cert, 0);
       if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND)
         {
-          print_cert_info(session, GNUTLS_CRT_PRINT_COMPACT);
+          print_cert_info(session, GNUTLS_CRT_PRINT_COMPACT, 0);
           fprintf(stderr, "Host %s has never been contacted before and is not 
in the trusted list.\n", hostname);
           if (status == 0)
             fprintf(stderr, "Its certificate is valid for %s.\n", hostname);
@@ -489,7 +503,7 @@ cert_verify_callback (gnutls_session_t session)
         }
       else if (rc == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
         {
-          print_cert_info(session, GNUTLS_CRT_PRINT_COMPACT);
+          print_cert_info(session, GNUTLS_CRT_PRINT_COMPACT, 0);
           fprintf(stderr, "Warning: host %s is known and it is associated with 
a different key.\n", hostname);
           fprintf(stderr, "It might be that the server has multiple keys, or 
an attacker replaced the key to eavesdrop this connection .\n");
           if (status == 0)
@@ -505,10 +519,11 @@ cert_verify_callback (gnutls_session_t session)
           return -1;
         }
       
-      rc = gnutls_store_pubkey(NULL, NULL, hostname, service, GNUTLS_CRT_X509, 
cert, 0);
-      if (rc < 0)
+      if (rc != 0)
         {
-          fprintf(stderr, "Could not store key: %s\n", gnutls_strerror(rc));
+          rc = gnutls_store_pubkey(NULL, NULL, hostname, service, 
GNUTLS_CRT_X509, cert, 0);
+          if (rc < 0)
+            fprintf(stderr, "Could not store key: %s\n", gnutls_strerror(rc));
         }
     }
 
@@ -1077,6 +1092,10 @@ const char* rest = NULL;
       priorities = OPT_ARG(PRIORITY);
     } 
   verbose = HAVE_OPT( VERBOSE);
+  if (verbose)
+    print_cert = 1;
+  else
+    print_cert = HAVE_OPT( PRINT_CERT);
   
   if (HAVE_OPT(LIST))
     {
@@ -1085,7 +1104,6 @@ const char* rest = NULL;
     }
 
   disable_extensions = HAVE_OPT( DISABLE_EXTENSIONS);
-  print_cert = HAVE_OPT( PRINT_CERT);
   starttls = HAVE_OPT(STARTTLS);
   resume = HAVE_OPT(RESUME);
   rehandshake = HAVE_OPT(REHANDSHAKE);
@@ -1228,7 +1246,7 @@ do_handshake (socket_st * socket)
   if (ret == 0)
     {
       /* print some information */
-      print_info (socket->session, socket->hostname, HAVE_OPT(INSECURE));
+      print_info (socket->session, print_cert);
       socket->secure = 1;
     }
   else
@@ -1440,4 +1458,76 @@ init_global_tls_stuff (void)
 
 }
 
+/* OCSP check for the peer's certificate. Should be called 
+ * only after the certificate list verication is complete.
+ * Returns:
+ * 0: certificate is revoked
+ * 1: certificate is ok
+ * -1: dunno
+ */
+static int
+cert_verify_ocsp (gnutls_session_t session)
+{
+  gnutls_x509_crt_t crt, issuer;
+  const gnutls_datum_t *cert_list;
+  unsigned int cert_list_size = 0;
+  int deinit_issuer = 0;
+  gnutls_datum_t resp;
+  int ret;
 
+  cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
+  if (cert_list_size == 0)
+    {
+      fprintf (stderr, "No certificates found!\n");
+      return -1;
+    }
+
+  gnutls_x509_crt_init (&crt);
+  ret =
+      gnutls_x509_crt_import (crt, &cert_list[0],
+                              GNUTLS_X509_FMT_DER);
+  if (ret < 0)
+    {
+      fprintf (stderr, "Decoding error: %s\n",
+               gnutls_strerror (ret));
+      return -1;
+    }
+    
+  ret = gnutls_certificate_get_issuer(xcred, crt, &issuer, 0);
+  if (ret < 0 && cert_list_size > 1)
+    {
+      gnutls_x509_crt_init(&issuer);
+      ret = gnutls_x509_crt_import(issuer, &cert_list[1], GNUTLS_X509_FMT_DER);
+      if (ret < 0)
+        {
+          fprintf (stderr, "Decoding error: %s\n",
+                   gnutls_strerror (ret));
+           return -1;
+        }
+      deinit_issuer = 1;
+    }
+  else if (ret < 0)
+    {
+      fprintf(stderr, "Cannot find issuer\n");
+      ret = -1;
+      goto cleanup;
+    }
+    
+  ret = send_ocsp_request(NULL, crt, issuer, &resp, 1);
+  if (ret < 0)
+    {
+      fprintf(stderr, "Cannot contact OCSP server\n");
+      ret = -1;
+      goto cleanup;
+    }
+
+  /* verify and check the response for revoked cert */
+  ret = check_ocsp_response(issuer, &resp);
+
+cleanup:
+  if (deinit_issuer)
+    gnutls_x509_crt_deinit (issuer);
+  gnutls_x509_crt_deinit (crt);
+
+  return ret;
+}
diff --git a/src/common.c b/src/common.c
index 38ea2cf..c98ad04 100644
--- a/src/common.c
+++ b/src/common.c
@@ -39,7 +39,6 @@
 
 #define SU(x) (x!=NULL?x:"Unknown")
 
-int print_cert;
 extern int verbose;
 
 const char str_unknown[] = "(unknown)";
@@ -106,14 +105,14 @@ print_x509_info_compact (gnutls_session_t session, int 
flag)
 }
 
 static void
-print_x509_info (gnutls_session_t session, int flag)
+print_x509_info (gnutls_session_t session, int flag, int print_cert)
 {
     gnutls_x509_crt_t crt;
     const gnutls_datum_t *cert_list;
     unsigned int cert_list_size = 0, j;
     int ret;
     
-    if (flag == GNUTLS_CRT_PRINT_COMPACT)
+    if (flag == GNUTLS_CRT_PRINT_COMPACT && print_cert == 0)
       return print_x509_info_compact(session, flag);
 
     cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
@@ -330,7 +329,7 @@ print_openpgp_info_compact (gnutls_session_t session, int 
flag)
 }
 
 static void
-print_openpgp_info (gnutls_session_t session, int flag)
+print_openpgp_info (gnutls_session_t session, int flag, int print_cert)
 {
 
     gnutls_openpgp_crt_t crt;
@@ -338,7 +337,7 @@ print_openpgp_info (gnutls_session_t session, int flag)
     unsigned int cert_list_size = 0;
     int ret;
 
-    if (flag == GNUTLS_CRT_PRINT_COMPACT)
+    if (flag == GNUTLS_CRT_PRINT_COMPACT && print_cert == 0)
       print_openpgp_info_compact(session, flag);
     
     printf (" - Certificate type: OpenPGP\n");
@@ -409,7 +408,8 @@ print_openpgp_info (gnutls_session_t session, int flag)
 
 #endif
 
-/* returns false (0) if not verified, or true (1) otherwise */
+/* returns false (0) if not verified, or true (1) otherwise 
+ */
 int
 cert_verify (gnutls_session_t session, const char* hostname)
 {
@@ -483,7 +483,7 @@ cert_verify (gnutls_session_t session, const char* hostname)
 }
 
 static void
-print_dh_info (gnutls_session_t session, const char *str)
+print_dh_info (gnutls_session_t session, const char *str, int print)
 {
     printf ("- %sDiffie-Hellman parameters\n", str);
     printf (" - Using prime: %d bits\n",
@@ -493,7 +493,7 @@ print_dh_info (gnutls_session_t session, const char *str)
     printf (" - Peer's public key: %d bits\n",
             gnutls_dh_get_peers_public_bits (session));
 
-    if (print_cert)
+    if (print)
       {
           int ret;
           gnutls_datum_t raw_gen = { NULL, 0 };
@@ -581,13 +581,12 @@ print_ecdh_info (gnutls_session_t session, const char 
*str)
 }
 
 int
-print_info (gnutls_session_t session, const char *hostname, int insecure)
+print_info (gnutls_session_t session, int print_cert)
 {
     const char *tmp;
     gnutls_credentials_type_t cred;
     gnutls_kx_algorithm_t kx;
     unsigned char session_id[33];
-    int ret;
     size_t session_id_size = sizeof (session_id);
 
     /* print session ID */
@@ -607,7 +606,7 @@ print_info (gnutls_session_t session, const char *hostname, 
int insecure)
           if (kx == GNUTLS_KX_ANON_ECDH)
               print_ecdh_info (session, "Anonymous ");
           else
-              print_dh_info (session, "Anonymous ");
+              print_dh_info (session, "Anonymous ", verbose);
           break;
 #endif
 #ifdef ENABLE_SRP
@@ -633,7 +632,7 @@ print_info (gnutls_session_t session, const char *hostname, 
int insecure)
               printf ("- PSK authentication. Connected as '%s'\n",
                       gnutls_psk_server_get_username (session));
           if (kx == GNUTLS_KX_DHE_PSK)
-              print_dh_info (session, "Ephemeral ");
+              print_dh_info (session, "Ephemeral ", verbose);
           if (kx == GNUTLS_KX_ECDHE_PSK)
               print_ecdh_info (session, "Ephemeral ");
           break;
@@ -655,17 +654,12 @@ print_info (gnutls_session_t session, const char 
*hostname, int insecure)
                 }
           }
 
-          print_cert_info (session, 
verbose?GNUTLS_CRT_PRINT_FULL:GNUTLS_CRT_PRINT_COMPACT);
-
-          ret = cert_verify (session, hostname);
-          if (insecure == 0 && ret == 0)
-            {
-              fprintf(stderr, "Exiting because verification failed (use 
--insecure to force connection)\n");
-              exit(1);
-            }
+          print_cert_info (session, 
+                           
verbose?GNUTLS_CRT_PRINT_FULL:GNUTLS_CRT_PRINT_COMPACT, 
+                           print_cert);
 
           if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
-              print_dh_info (session, "Ephemeral ");
+              print_dh_info (session, "Ephemeral ", verbose);
           else if (kx == GNUTLS_KX_ECDHE_RSA
                    || kx == GNUTLS_KX_ECDHE_ECDSA)
               print_ecdh_info (session, "Ephemeral ");
@@ -721,7 +715,7 @@ print_info (gnutls_session_t session, const char *hostname, 
int insecure)
 }
 
 void
-print_cert_info (gnutls_session_t session, int flag)
+print_cert_info (gnutls_session_t session, int flag, int print_cert)
 {
 
     if (gnutls_certificate_client_get_request_status (session) != 0)
@@ -730,11 +724,11 @@ print_cert_info (gnutls_session_t session, int flag)
     switch (gnutls_certificate_type_get (session))
       {
       case GNUTLS_CRT_X509:
-          print_x509_info (session, flag);
+          print_x509_info (session, flag, print_cert);
           break;
 #ifdef ENABLE_OPENPGP
       case GNUTLS_CRT_OPENPGP:
-          print_openpgp_info (session, flag);
+          print_openpgp_info (session, flag, print_cert);
           break;
 #endif
       default:
diff --git a/src/common.h b/src/common.h
index aeeb395..1e6ca37 100644
--- a/src/common.h
+++ b/src/common.h
@@ -49,8 +49,8 @@
 
 extern const char str_unknown[];
 
-int print_info (gnutls_session_t state, const char *hostname, int insecure);
-void print_cert_info (gnutls_session_t, int flag);
+int print_info (gnutls_session_t state, int print_cert);
+void print_cert_info (gnutls_session_t, int flag, int print_cert);
 void print_list (const char* priorities, int verbose);
 int cert_verify (gnutls_session_t session, const char* hostname);
 
diff --git a/src/ocsptool-args.def.in b/src/ocsptool-args.def.in
index 44fdac6..4db0eff 100644
--- a/src/ocsptool-args.def.in
+++ b/src/ocsptool-args.def.in
@@ -3,8 +3,9 @@ prog-name     = ocsptool;
 prog-title    = "GnuTLS OCSP tool";
 prog-desc     = "Program to handle OCSP request/responses.";
 help-value = "h";
-detail    = "Ocsptool can parse OCSP request/responses, generate OCSP requests 
and  verify OCSP responses.";
-
+detail    = "Ocsptool is a program that can parse and print information about
+OCSP requests/responses, generate requests and verify responses.
+";
 short-usage   = "ocsptool [options]\nocsptool --help for usage 
instructions.\n";
 prog-group    = "GnuTLS";
 explain       = "";
@@ -167,9 +168,142 @@ flag = {
 
 doc-section = {
   ds-type = 'SEE ALSO';
-  ds-format = 'man';
+  ds-format = 'texi';
   ds-text   = <<-_EOT_
     certtool (1)
 _EOT_;
 };
 
+doc-section = {
+  ds-type = 'EXAMPLES';
+  ds-format = 'texi';
+  ds-text   = <<-_EOF_
address@hidden Print information about an OCSP request
+
+To parse an OCSP request and print information about the content, the
address@hidden or @code{--request-info} parameter may be used as follows.
+The @code{-Q} parameter specify the name of the file containing the
+OCSP request, and it should contain the OCSP request in binary DER
+format.
+
address@hidden
+$ ocsptool -i -Q ocsp-request.der
address@hidden example
+
+The input file may also be sent to standard input like this:
+
address@hidden
+$ cat ocsp-request.der | ocsptool --request-info
address@hidden example
+
address@hidden Print information about an OCSP response
+
+Similar to parsing OCSP requests, OCSP responses can be parsed using
+the @code{-j} or @code{--response-info} as follows.
+
address@hidden
+$ ocsptool -j -Q ocsp-response.der
+$ cat ocsp-response.der | ocsptool --response-info
address@hidden example
+
address@hidden Generate an OCSP request
+
+The @code{-q} or @code{--generate-request} parameters are used to
+generate an OCSP request.  By default the OCSP request is written to
+standard output in binary DER format, but can be stored in a file
+using @code{--outfile}.  To generate an OCSP request the issuer of the
+certificate to check needs to be specified with @code{--load-issuer}
+and the certificate to check with @code{--load-cert}.  By default PEM
+format is used for these files, although @code{--inder} can be used to
+specify that the input files are in DER format.
+
address@hidden
+$ ocsptool -q --load-issuer issuer.pem --load-cert client.pem --outfile 
ocsp-request.der
address@hidden example
+
+When generating OCSP requests, the tool will add an OCSP extension
+containing a nonce.  This behaviour can be disabled by specifying
address@hidden
+
address@hidden Verify signature in OCSP response
+
+To verify the signature in an OCSP response the @code{-e} or
address@hidden parameter is used.  The tool will read an
+OCSP response in DER format from standard input, or from the file
+specified by @code{--load-response}.  The OCSP response is verified
+against a set of trust anchors, which are specified using
address@hidden  The trust anchors are concatenated certificates
+in PEM format.  The certificate that signed the OCSP response needs to
+be in the set of trust anchors, or the issuer of the signer
+certificate needs to be in the set of trust anchors and the OCSP
+Extended Key Usage bit has to be asserted in the signer certificate.
+
address@hidden
+$ ocsptool -e --load-trust issuer.pem --load-response ocsp-response.der
address@hidden example
+
+The tool will print status of verification.
+
address@hidden Verify signature in OCSP response against given certificate
+
+It is possible to override the normal trust logic if you know that a
+certain certificate is supposed to have signed the OCSP response, and
+you want to use it to check the signature.  This is achieved using
address@hidden instead of @code{--load-trust}.  This will load
+one certificate and it will be used to verify the signature in the
+OCSP response.  It will not check the Extended Key Usage bit.
+
address@hidden
+$ ocsptool -e --load-signer ocsp-signer.pem --load-response ocsp-response.der
address@hidden example
+
+This approach is normally only relevant in two situations.  The first
+is when the OCSP response does not contain a copy of the signer
+certificate, so the @code{--load-trust} code would fail.  The second
+is if you want to avoid the indirect mode where the OCSP response
+signer certificate is signed by a trust anchor.
+
address@hidden Real-world example
+
+Here is an example of how to generate an OCSP request for a
+certificate and to verify the response.  For illustration we'll use
+the @code{blog.josefsson.org} host, which (as of writing) uses a
+certificate from CACert.  First we'll use @code{gnutls-cli} to get a
+copy of the server certificate chain.  The server is not required to
+send this information, but this particular one is configured to do so.
+
address@hidden
+$ echo | gnutls-cli -p 443 blog.josefsson.org --print-cert > chain.pem
address@hidden example
+
+Use a text editor on @code{chain.pem} to create three files for each
+separate certificates, called @code{cert.pem} for the first
+certificate for the domain itself, secondly @code{issuer.pem} for the
+intermediate certificate and @code{root.pem} for the final root
+certificate.
+
+The domain certificate normally contains a pointer to where the OCSP
+responder is located, in the Authority Information Access Information
+extension.  For example, from @code{certtool -i < cert.pem} there is
+this information:
+
address@hidden
+               Authority Information Access Information (not critical):
+                       Access Method: 1.3.6.1.5.5.7.48.1 (id-ad-ocsp)
+                       Access Location URI: http://ocsp.CAcert.org/
address@hidden example
+
+This means the CA support OCSP queries over HTTP.  We are now ready to
+create a OCSP request for the certificate.
+
address@hidden
+$ ocsptool --ask ocsp.CAcert.org --load-issuer issuer.pem  --load-cert 
cert.pem \
+           --outfile ocsp-request.der
address@hidden example
+
+The request is sent via HTTP to the OCSP server address specified. If the
+address is ommited ocsptool will use the address stored in the certificate.
+
+_EOF_;
+};
+
diff --git a/src/ocsptool-common.c b/src/ocsptool-common.c
new file mode 100644
index 0000000..d74e553
--- /dev/null
+++ b/src/ocsptool-common.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/ocsp.h>
+#include <gnutls/x509.h>
+#include <gnutls/crypto.h>
+
+/* Gnulib portability files. */
+#include <error.h>
+#include <progname.h>
+#include <version-etc.h>
+#include <read-file.h>
+#include <socket.h>
+
+#include <ocsptool-common.h>
+
+#define MAX_BUF 4*1024
+#define HEADER_PATTERN "POST / HTTP/1.1\r\n" \
+  "Host: %s\r\n" \
+  "Accept: */*\r\n" \
+  "Content-Type: application/ocsp-request\r\n" \
+  "Content-Length: %u\r\n" \
+  "Connection: close\r\n\r\n"
+static char buffer[MAX_BUF + 1];
+
+/* returns the host part of a URL */
+static const char* host_from_url(const char* url, unsigned int* port)
+{
+static char hostname[512];
+char * p;
+
+  *port = 0;
+
+  if ((p=strstr(url, "http://";)) != NULL)
+    {
+      snprintf(hostname, sizeof(hostname), "%s", p+7);
+      p = strchr(hostname, '/');
+      if (p != NULL) *p = 0;
+
+      p = strchr(hostname, ':');
+      if (p != NULL) {
+        *p = 0;
+        *port = atoi(p+1);
+      }
+      
+      return hostname;
+    }
+  else
+    {
+      return url;
+    }
+}
+
+void
+_generate_request (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
+                   gnutls_datum_t * rdata, int nonce)
+{
+  gnutls_ocsp_req_t req;
+  int ret;
+
+  ret = gnutls_ocsp_req_init (&req);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "ocsp_req_init: %s", gnutls_strerror (ret));
+
+  ret = gnutls_ocsp_req_add_cert (req, GNUTLS_DIG_SHA1,
+                                     issuer, cert);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "ocsp_req_add_cert: %s", gnutls_strerror (ret));
+    
+  if (nonce)
+    {
+      unsigned char noncebuf[23];
+      gnutls_datum_t nonce = { noncebuf, sizeof (noncebuf) };
+
+      ret = gnutls_rnd (GNUTLS_RND_RANDOM, nonce.data, nonce.size);
+      if (ret < 0)
+       error (EXIT_FAILURE, 0, "gnutls_rnd: %s", gnutls_strerror (ret));
+
+      ret = gnutls_ocsp_req_set_nonce (req, 0, &nonce);
+      if (ret < 0)
+       error (EXIT_FAILURE, 0, "ocsp_req_set_nonce: %s",
+              gnutls_strerror (ret));
+    }
+
+  ret = gnutls_ocsp_req_export (req, rdata);
+  if (ret != 0)
+    error (EXIT_FAILURE, 0, "ocsp_req_export: %s", gnutls_strerror (ret));
+
+  gnutls_ocsp_req_deinit (req);
+  return;
+}
+
+static size_t get_data(void *buffer, size_t size, size_t nmemb, void *userp)
+{
+gnutls_datum_t *ud = userp;
+  
+  size *= nmemb;
+
+  ud->data = realloc(ud->data, size+ud->size);
+  if (ud->data == NULL)
+    {
+      fprintf(stderr, "Not enough memory for the request\n");
+      exit(1);
+    }
+
+  memcpy(&ud->data[ud->size], buffer, size);
+  ud->size += size;
+  
+  return size;
+}
+
+int send_ocsp_request(const char* server,
+                       gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
+                       gnutls_datum_t * resp_data, int nonce)
+{
+gnutls_datum_t ud;
+int ret;
+gnutls_datum_t req;
+char* url = (void*)server;
+char headers[1024];
+char service[16];
+unsigned char * p;
+const char *hostname;
+unsigned int headers_size = 0, port;
+socket_st hd;
+
+  sockets_init ();
+
+  if (url == NULL)
+    {
+      /* try to read URL from issuer certificate */
+      gnutls_datum_t data;
+      
+      ret = gnutls_x509_crt_get_authority_info_access(cert, 0, 
+                                  GNUTLS_IA_OCSP_URI, &data, NULL);
+      
+      if (ret < 0)
+        ret = gnutls_x509_crt_get_authority_info_access(issuer, 0, 
+                                    GNUTLS_IA_OCSP_URI, &data, NULL);
+      if (ret < 0)
+        {
+          fprintf(stderr, "Cannot find URL from issuer: %s\n", 
gnutls_strerror(ret));
+          exit(1);  
+        }
+      
+      url = malloc(data.size+1);
+      memcpy(url, data.data, data.size);
+      url[data.size] = 0;
+      
+      gnutls_free(data.data);
+    }
+    
+  hostname = host_from_url(url, &port);
+  if (port != 0)
+    snprintf(service, sizeof(service), "%u", port);
+  else strcpy(service, "80");
+  
+  fprintf(stderr, "Connecting to OCSP server: %s...\n", hostname);
+
+  memset(&ud, 0, sizeof(ud));
+
+  _generate_request(cert, issuer, &req, nonce);
+
+  snprintf(headers, sizeof(headers), HEADER_PATTERN, hostname, (unsigned 
int)req.size);
+  headers_size = strlen(headers);
+  
+  socket_open(&hd, hostname, service, 0);
+  socket_connect (&hd);
+  
+  socket_send(&hd, headers, headers_size);
+  socket_send(&hd, req.data, req.size);
+  
+  do {
+    ret = socket_recv(&hd, buffer, sizeof(buffer));
+    if (ret > 0) get_data(buffer, ret, 1, &ud);
+  } while(ret > 0);
+  
+  if (ret < 0 || ud.size == 0)
+    {
+      perror("recv");
+      exit(1);
+    }
+  
+  socket_bye(&hd);
+  
+  p = memmem(ud.data, ud.size, "\r\n\r\n", 4);
+  if (p == NULL)
+    {
+      fprintf(stderr, "Cannot interpret HTTP response\n");
+      exit(1);
+    }
+  
+  p += 4;
+  resp_data->size = ud.size - (p - ud.data);
+  resp_data->data = malloc(resp_data->size);
+  if (resp_data->data == NULL)
+    exit(1);
+  
+  memcpy(resp_data->data, p, resp_data->size);
+
+  free(ud.data);
+  
+  return 0;
+}
+
+void
+print_ocsp_verify_res (unsigned int output)
+{
+  int comma = 0;
+
+  if (output)
+    {
+      printf ("Failure");
+      comma = 1;
+    }
+  else
+    {
+      printf ("Success");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Signer cert not found");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Signer cert keyusage error");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Signer cert is not trusted");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Insecure algorithm");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Signature failure");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Signer cert not yet activated");
+      comma = 1;
+    }
+
+  if (output & GNUTLS_OCSP_VERIFY_CERT_EXPIRED)
+    {
+      if (comma)
+        printf (", ");
+      printf ("Signer cert expired");
+      comma = 1;
+    }
+}
+
+/* Returns:
+ *  0: certificate is revoked
+ *  1: certificate is ok
+ *  -1: dunno
+ */
+int
+check_ocsp_response (gnutls_x509_crt_t issuer,
+                     gnutls_datum_t *data)
+{
+  gnutls_ocsp_resp_t resp;
+  int ret;
+  unsigned int status, cert_status;
+  time_t rtime, ttime;
+
+  ret = gnutls_ocsp_resp_init (&resp);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "ocsp_resp_init: %s", gnutls_strerror (ret));
+
+  ret = gnutls_ocsp_resp_import (resp, data);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "importing response: %s", gnutls_strerror (ret));
+
+  ret = gnutls_ocsp_resp_verify_direct( resp, issuer, &status, 0);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "gnutls_ocsp_resp_verify_direct: %s",
+      gnutls_strerror (ret));
+
+  if (status != 0)
+    {
+      printf ("*** Verifying OCSP Response: ");
+      print_ocsp_verify_res (status);
+      printf (".\n");
+    }
+
+  /* do not print revocation data if response was not verified */
+  if (status != 0)
+    {
+      ret = -1;
+      goto cleanup;
+    }
+
+  ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
+        &cert_status, &ttime, NULL, &rtime, NULL);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "reading response: %s", gnutls_strerror (ret));
+  
+  if (cert_status == GNUTLS_OCSP_CERT_REVOKED)
+    {
+      printf("*** Certificate was revoked at %s", ctime(&rtime));
+      ret = 0;
+      goto cleanup;
+    }
+  
+  printf("- OCSP server flags certificate not revoked as of %s", 
ctime(&ttime));
+  ret = 1;
+cleanup:
+  gnutls_ocsp_resp_deinit (resp);
+  
+  return ret;
+}
+
diff --git a/src/ocsptool-common.h b/src/ocsptool-common.h
index 729d1eb..455b564 100644
--- a/src/ocsptool-common.h
+++ b/src/ocsptool-common.h
@@ -21,6 +21,8 @@
 #ifndef OCSPTOOL_COMMON_H
 #define OCSPTOOL_COMMON_H
 
+#include <gnutls/ocsp.h>
+
 enum
   {
     ACTION_NONE,
@@ -31,5 +33,16 @@ enum
   };
 
 extern void ocsptool_version (void);
+void
+_generate_request (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
+                   gnutls_datum_t * rdata, int nonce);
+int send_ocsp_request(const char* server,
+                       gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
+                       gnutls_datum_t * resp_data, int nonce);
+void
+print_ocsp_verify_res (unsigned int output);
+
+int
+check_ocsp_response (gnutls_x509_crt_t issuer, gnutls_datum_t *data);
 
 #endif
diff --git a/src/ocsptool.c b/src/ocsptool.c
index 0e48e44..7f93369 100644
--- a/src/ocsptool.c
+++ b/src/ocsptool.c
@@ -193,59 +193,11 @@ load_cert (void)
 }
 
 static void
-_generate_request (gnutls_datum_t * rdata)
-{
-  gnutls_ocsp_req_t req;
-  int ret;
-  gnutls_datum_t dat;
-  gnutls_x509_crt_t issuer, cert;
-
-  ret = gnutls_ocsp_req_init (&req);
-  if (ret < 0)
-    error (EXIT_FAILURE, 0, "ocsp_req_init: %s", gnutls_strerror (ret));
-
-  issuer = load_issuer ();
-  cert = load_cert ();
-  
-  ret = gnutls_ocsp_req_add_cert (req, GNUTLS_DIG_SHA1,
-                                     issuer, cert);
-  if (ret < 0)
-    error (EXIT_FAILURE, 0, "ocsp_req_add_cert: %s", gnutls_strerror (ret));
-    
-  gnutls_x509_crt_deinit (issuer);
-  gnutls_x509_crt_deinit (cert);
-
-  if (ENABLED_OPT(NONCE))
-    {
-      unsigned char noncebuf[23];
-      gnutls_datum_t nonce = { noncebuf, sizeof (noncebuf) };
-
-      ret = gnutls_rnd (GNUTLS_RND_RANDOM, nonce.data, nonce.size);
-      if (ret < 0)
-       error (EXIT_FAILURE, 0, "gnutls_rnd: %s", gnutls_strerror (ret));
-
-      ret = gnutls_ocsp_req_set_nonce (req, 0, &nonce);
-      if (ret < 0)
-       error (EXIT_FAILURE, 0, "ocsp_req_set_nonce: %s",
-              gnutls_strerror (ret));
-    }
-
-  ret = gnutls_ocsp_req_export (req, &dat);
-  if (ret != 0)
-    error (EXIT_FAILURE, 0, "ocsp_req_export: %s", gnutls_strerror (ret));
-
-  gnutls_ocsp_req_deinit (req);
-
-  memcpy(rdata, &dat, sizeof(*rdata));
-  return;
-}
-
-static void
 generate_request (void)
 {
   gnutls_datum_t dat;
   
-  _generate_request(&dat);
+  _generate_request(load_cert(), load_issuer(), &dat, ENABLED_OPT(NONCE));
 
   fwrite (dat.data, 1, dat.size, outfile);
 
@@ -253,79 +205,6 @@ generate_request (void)
 }
 
 
-static void
-print_verify_res (unsigned int output)
-{
-  int comma = 0;
-
-  if (output)
-    {
-      printf ("Failure");
-      comma = 1;
-    }
-  else
-    {
-      printf ("Success");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Signer cert not found");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Signer cert keyusage error");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Signer cert is not trusted");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Insecure algorithm");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Signature failure");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Signer cert not yet activated");
-      comma = 1;
-    }
-
-  if (output & GNUTLS_OCSP_VERIFY_CERT_EXPIRED)
-    {
-      if (comma)
-        printf (", ");
-      printf ("Signer cert expired");
-      comma = 1;
-    }
-}
-
 static int
 _verify_response (gnutls_datum_t *data)
 {
@@ -347,7 +226,7 @@ _verify_response (gnutls_datum_t *data)
   if (ret < 0)
     error (EXIT_FAILURE, 0, "importing response: %s", gnutls_strerror (ret));
 
-  if (!HAVE_OPT(LOAD_SIGNER) && HAVE_OPT(LOAD_TRUST))
+  if (HAVE_OPT(LOAD_TRUST))
     {
       dat.data = (void*)read_binary_file (OPT_ARG(LOAD_TRUST), &size);
       if (dat.data == NULL)
@@ -365,10 +244,10 @@ _verify_response (gnutls_datum_t *data)
        error (EXIT_FAILURE, 0, "error parsing CAs: %s",
               gnutls_strerror (ret));
 
-#if 0
       if (HAVE_OPT(VERBOSE))
        {
          unsigned int i;
+         printf ("Trust anchors:\n");
          for (i = 0; i < x509_ncas; i++)
            {
              gnutls_datum_t out;
@@ -379,11 +258,11 @@ _verify_response (gnutls_datum_t *data)
                error (EXIT_FAILURE, 0, "gnutls_x509_crt_print: %s",
                       gnutls_strerror (ret));
 
-             printf ("Trust anchor %d: %.*s\n", i, out.size, out.data);
+             printf ("%d: %.*s\n", i, out.size, out.data);
              gnutls_free (out.data);
            }
+          printf("\n");
        }
-#endif
 
       ret = gnutls_x509_trust_list_add_cas (list, x509_ca_list, x509_ncas, 0);
       if (ret < 0)
@@ -398,7 +277,7 @@ _verify_response (gnutls_datum_t *data)
        error (EXIT_FAILURE, 0, "gnutls_ocsp_resp_verify: %s",
               gnutls_strerror (ret));
     }
-  else if (!HAVE_OPT(LOAD_TRUST) && HAVE_OPT(LOAD_SIGNER))
+  else if (HAVE_OPT(LOAD_SIGNER))
     {
       ret = gnutls_x509_crt_init (&signer);
       if (ret < 0)
@@ -426,6 +305,7 @@ _verify_response (gnutls_datum_t *data)
 
          printf ("Signer: %.*s\n", out.size, out.data);
          gnutls_free (out.data);
+          printf("\n");
        }
 
       ret = gnutls_ocsp_resp_verify_direct (resp, signer, &verify, 0);
@@ -437,7 +317,7 @@ _verify_response (gnutls_datum_t *data)
     error (EXIT_FAILURE, 0, "missing --load-trust or --load-signer");
 
   printf ("Verifying OCSP Response: ");
-  print_verify_res (verify);
+  print_ocsp_verify_res (verify);
   printf (".\n");
 
   gnutls_ocsp_resp_deinit (resp);
@@ -462,142 +342,22 @@ verify_response (void)
   _verify_response(&dat);
 }
 
-static size_t get_data(void *buffer, size_t size, size_t nmemb, void *userp)
+static void ask_server(const char* url)
 {
-gnutls_datum_t *ud = userp;
-  
-  size *= nmemb;
-
-  ud->data = realloc(ud->data, size+ud->size);
-  if (ud->data == NULL)
-    {
-      fprintf(stderr, "Not enough memory for the request\n");
-      exit(1);
-    }
-
-  memcpy(&ud->data[ud->size], buffer, size);
-  ud->size += size;
-  
-  return size;
-}
-
-/* returns the host part of a URL */
-static const char* host_from_url(const char* url, unsigned int* port)
-{
-static char hostname[512];
-char * p;
-
-  *port = 0;
-
-  if ((p=strstr(url, "http://";)) != NULL)
-    {
-      snprintf(hostname, sizeof(hostname), "%s", p+7);
-      p = strchr(hostname, '/');
-      if (p != NULL) *p = 0;
-
-      p = strchr(hostname, ':');
-      if (p != NULL) {
-        *p = 0;
-        *port = atoi(p+1);
-      }
-      
-      return hostname;
-    }
-  else
-    {
-      return url;
-    }
-}
-
-#define MAX_BUF 4*1024
-#define HEADER_PATTERN "POST / HTTP/1.1\r\n" \
-  "Host: %s\r\n" \
-  "Accept: */*\r\n" \
-  "Content-Type: application/ocsp-request\r\n" \
-  "Content-Length: %u\r\n" \
-  "Connection: close\r\n\r\n"
-static char buffer[MAX_BUF + 1];
-
-static void ask_server(const char* _url)
-{
-gnutls_datum_t ud, resp_data;
+gnutls_datum_t resp_data;
 int ret, v;
-gnutls_datum_t req;
-char* url = (void*)_url;
-char headers[1024];
-char service[16];
-const char *hostname;
-unsigned int headers_size = 0, port;
-socket_st hd;
-
-  sockets_init ();
-
-  if (url == NULL)
-    {
-      /* try to read URL from issuer certificate */
-      gnutls_x509_crt_t issuer = load_issuer();
-      gnutls_datum_t data;
-      
-      ret = gnutls_x509_crt_get_authority_info_access(issuer, 0, 
-                                  GNUTLS_IA_OCSP_URI, &data, NULL);
-      if (ret < 0)
-        {
-          fprintf(stderr, "Cannot find URL from issuer: %s\n", 
gnutls_strerror(ret));
-          exit(1);  
-        }
-      
-      url = malloc(data.size+1);
-      memcpy(url, data.data, data.size);
-      url[data.size] = 0;
-      
-      gnutls_free(data.data);
-      
-      gnutls_x509_crt_deinit(issuer);
-    }
-    
-  hostname = host_from_url(url, &port);
-  if (port != 0)
-    snprintf(service, sizeof(service), "%u", port);
-  else strcpy(service, "80");
-  
-  fprintf(stderr, "Connecting to %s\n", hostname);
+gnutls_x509_crt_t cert, issuer;
 
-  memset(&ud, 0, sizeof(ud));
-
-  _generate_request(&req);
-
-  snprintf(headers, sizeof(headers), HEADER_PATTERN, hostname, (unsigned 
int)req.size);
-  headers_size = strlen(headers);
-  
-  socket_open(&hd, hostname, service, 0);
-  socket_connect (&hd);
-  
-  socket_send(&hd, headers, headers_size);
-  socket_send(&hd, req.data, req.size);
-  
-  do {
-    ret = socket_recv(&hd, buffer, sizeof(buffer));
-    if (ret > 0) get_data(buffer, ret, 1, &ud);
-  } while(ret > 0);
-  
-  if (ret < 0 || ud.size == 0)
-    {
-      perror("recv");
-      exit(1);
-    }
+  cert = load_cert();
+  issuer = load_issuer();
   
-  socket_bye(&hd);
-  
-  resp_data.data = memmem(ud.data, ud.size, "\r\n\r\n", 4);
-  if (resp_data.data == NULL)
+  ret = send_ocsp_request(url, cert, issuer, &resp_data, ENABLED_OPT(NONCE));
+  if (ret < 0)
     {
-      fprintf(stderr, "Cannot interpret HTTP response\n");
+      fprintf(stderr, "Cannot send OCSP request\n");
       exit(1);
     }
   
-  resp_data.data += 4;
-  resp_data.size = ud.size - (resp_data.data - ud.data);
-  
   _response_info (&resp_data);
 
   if (HAVE_OPT(LOAD_SIGNER) || HAVE_OPT(LOAD_TRUST))
diff --git a/src/p11tool-args.def.in b/src/p11tool-args.def.in
index ea4839f..6a99c27 100644
--- a/src/p11tool-args.def.in
+++ b/src/p11tool-args.def.in
@@ -248,7 +248,7 @@ flag = {
 
 doc-section = {
   ds-type = 'SEE ALSO';
-  ds-format = 'man';
+  ds-format = 'texi';
   ds-text   = <<-_EOT_
     certtool (1)
 _EOT_;
diff --git a/src/psk-args.def.in b/src/psk-args.def.in
index a67dd72..a448af4 100644
--- a/src/psk-args.def.in
+++ b/src/psk-args.def.in
@@ -61,7 +61,7 @@ flag = {
 
 doc-section = {
   ds-type = 'SEE ALSO';
-  ds-format = 'man';
+  ds-format = 'texi';
   ds-text   = <<-_EOT_
     gnutls-cli-debug (1), gnutls-serv (1), srptool (1), certtool (1)
 _EOT_;
@@ -71,9 +71,14 @@ doc-section = {
   ds-type = 'EXAMPLES';
   ds-format = 'texi';
   ds-text   = <<-_EOT_
-To add a user 'test' in @file{passwd.psk} for use with GnuTLS run:
+To add a user 'psk_identity' in @file{passwd.psk} for use with GnuTLS run:
 @example
-$ psktool --passwd /etc/passwd.psk -u test
+$ ./psktool -u psk_identity -p passwd.psk
+Generating a random key for user 'psk_identity'
+Key stored to passwd.psk
+$ cat psks.txt
+psk_identity:88f3824b3e5659f52d00e959bacab954b6540344
+$
 @end example
 
 This command will create @file{/etc/passwd.psk} if it does not exist
diff --git a/src/serv-args.def.in b/src/serv-args.def.in
index 76d5697..d39d875 100644
--- a/src/serv-args.def.in
+++ b/src/serv-args.def.in
@@ -262,8 +262,180 @@ flag = {
 
 doc-section = {
   ds-type   = 'SEE ALSO'; // or anything else
-  ds-format = 'man';      // or texi or mdoc format
+  ds-format = 'texi';      // or texi or mdoc format
   ds-text   = <<-_EOText_
 gnutls-cli-debug(1), gnutls-cli(1)
 _EOText_;
 };
+
+doc-section = {
+  ds-type = 'EXAMPLES';
+  ds-format = 'texi';
+  ds-text   = <<-_EOF_
+Running your own TLS server based on GnuTLS can be useful when
+debugging clients and/or GnuTLS itself.  This section describes how to
+use @code{gnutls-serv} as a simple HTTPS server.
+
+The most basic server can be started as:
+
address@hidden
+gnutls-serv --http
address@hidden example
+
+It will only support anonymous ciphersuites, which many TLS clients
+refuse to use.
+
+The next step is to add support for X.509.  First we generate a CA:
+
address@hidden
+$ certtool --generate-privkey > x509-ca-key.pem
+$ echo 'cn = GnuTLS test CA' > ca.tmpl
+$ echo 'ca' >> ca.tmpl
+$ echo 'cert_signing_key' >> ca.tmpl
+$ certtool --generate-self-signed --load-privkey x509-ca-key.pem \
+  --template ca.tmpl --outfile x509-ca.pem
+...
address@hidden example
+
+Then generate a server certificate.  Remember to change the dns_name
+value to the name of your server host, or skip that command to avoid
+the field.
+
address@hidden
+$ certtool --generate-privkey > x509-server-key.pem
+$ echo 'organization = GnuTLS test server' > server.tmpl
+$ echo 'cn = test.gnutls.org' >> server.tmpl
+$ echo 'tls_www_server' >> server.tmpl
+$ echo 'encryption_key' >> server.tmpl
+$ echo 'signing_key' >> server.tmpl
+$ echo 'dns_name = test.gnutls.org' >> server.tmpl
+$ certtool --generate-certificate --load-privkey x509-server-key.pem \
+  --load-ca-certificate x509-ca.pem --load-ca-privkey x509-ca-key.pem \
+  --template server.tmpl --outfile x509-server.pem
+...
address@hidden example
+
+For use in the client, you may want to generate a client certificate
+as well.
+
address@hidden
+$ certtool --generate-privkey > x509-client-key.pem
+$ echo 'cn = GnuTLS test client' > client.tmpl
+$ echo 'tls_www_client' >> client.tmpl
+$ echo 'encryption_key' >> client.tmpl
+$ echo 'signing_key' >> client.tmpl
+$ certtool --generate-certificate --load-privkey x509-client-key.pem \
+  --load-ca-certificate x509-ca.pem --load-ca-privkey x509-ca-key.pem \
+  --template client.tmpl --outfile x509-client.pem
+...
address@hidden example
+
+To be able to import the client key/certificate into some
+applications, you will need to convert them into a PKCS#12 structure.
+This also encrypts the security sensitive key with a password.
+
address@hidden
+$ certtool --to-p12 --load-ca-certificate x509-ca.pem \
+  --load-privkey x509-client-key.pem --load-certificate x509-client.pem \
+  --outder --outfile x509-client.p12
address@hidden example
+
+For icing, we'll create a proxy certificate for the client too.
+
address@hidden
+$ certtool --generate-privkey > x509-proxy-key.pem
+$ echo 'cn = GnuTLS test client proxy' > proxy.tmpl
+$ certtool --generate-proxy --load-privkey x509-proxy-key.pem \
+  --load-ca-certificate x509-client.pem --load-ca-privkey x509-client-key.pem \
+  --load-certificate x509-client.pem --template proxy.tmpl \
+  --outfile x509-proxy.pem
+...
address@hidden example
+
+Then start the server again:
+
address@hidden
+$ gnutls-serv --http \
+            --x509cafile x509-ca.pem \
+            --x509keyfile x509-server-key.pem \
+            --x509certfile x509-server.pem
address@hidden example
+
+Try connecting to the server using your web browser.  Note that the
+server listens to port 5556 by default.
+
+While you are at it, to allow connections using DSA, you can also
+create a DSA key and certificate for the server.  These credentials
+will be used in the final example below.
+
address@hidden
+$ certtool --generate-privkey --dsa > x509-server-key-dsa.pem
+$ certtool --generate-certificate --load-privkey x509-server-key-dsa.pem \
+  --load-ca-certificate x509-ca.pem --load-ca-privkey x509-ca-key.pem \
+  --template server.tmpl --outfile x509-server-dsa.pem
+...
address@hidden example
+
+The next step is to create OpenPGP credentials for the server.
+
address@hidden
+gpg --gen-key
+...enter whatever details you want, use 'test.gnutls.org' as name...
address@hidden example
+
+Make a note of the OpenPGP key identifier of the newly generated key,
+here it was @code{5D1D14D8}.  You will need to export the key for
+GnuTLS to be able to use it.
+
address@hidden
+gpg -a --export 5D1D14D8 > openpgp-server.txt
+gpg --export 5D1D14D8 > openpgp-server.bin
+gpg --export-secret-keys 5D1D14D8 > openpgp-server-key.bin
+gpg -a --export-secret-keys 5D1D14D8 > openpgp-server-key.txt
address@hidden example
+
+Let's start the server with support for OpenPGP credentials:
+
address@hidden
+gnutls-serv --http \
+            --pgpkeyfile openpgp-server-key.txt \
+            --pgpcertfile openpgp-server.txt
address@hidden example
+
+The next step is to add support for SRP authentication. This requires
+an SRP password file created with @code{srptool}.
+To start the server with SRP support:
+
address@hidden
+gnutls-serv --http \
+            --srppasswdconf srp-tpasswd.conf \
+            --srppasswd srp-passwd.txt
address@hidden example
+
+Let's also start a server with support for PSK. This would require
+a password file created with @code{psktool}.
+
address@hidden
+gnutls-serv --http \
+            --pskpasswd psk-passwd.txt
address@hidden example
+
+Finally, we start the server with all the earlier parameters and you
+get this command:
+
address@hidden
+gnutls-serv --http \
+            --x509cafile x509-ca.pem \
+            --x509keyfile x509-server-key.pem \
+            --x509certfile x509-server.pem \
+            --x509dsakeyfile x509-server-key-dsa.pem \
+            --x509dsacertfile x509-server-dsa.pem \
+            --pgpkeyfile openpgp-server-key.txt \
+            --pgpcertfile openpgp-server.txt \
+            --srppasswdconf srp-tpasswd.conf \
+            --srppasswd srp-passwd.txt \
+            --pskpasswd psk-passwd.txt
address@hidden example
+_EOF_;
+};
+
diff --git a/src/serv.c b/src/serv.c
index 151ee30..d2277cb 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -1309,7 +1309,8 @@ static void tcp_server(const char* name, int port)
                                 human_addr ((struct sockaddr *)
                                             &client_address, calen, topbuf,
                                             sizeof (topbuf)));
-                        print_info (j->tls_session, NULL, 1);
+                        print_info (j->tls_session, verbose);
+                        cert_verify(j->tls_session, NULL);
                       }
                     j->handshake_ok = 1;
                   }
@@ -1432,7 +1433,8 @@ static void tcp_server(const char* name, int port)
                                             &client_address, calen, topbuf,
                                             sizeof (topbuf)));
 
-                        print_info (j->tls_session, NULL, 1);
+                        print_info (j->tls_session, verbose);
+                        cert_verify(j->tls_session, NULL);
                       }
                     j->handshake_ok = 1;
                   }
diff --git a/src/srptool-args.def.in b/src/srptool-args.def.in
index 6164d14..8456a66 100644
--- a/src/srptool-args.def.in
+++ b/src/srptool-args.def.in
@@ -95,7 +95,7 @@ containing the required for TLS parameters.";
 
 doc-section = {
   ds-type = 'SEE ALSO';
-  ds-format = 'man';
+  ds-format = 'texi';
   ds-text   = <<-_EOT_
     gnutls-cli-debug (1), gnutls-serv (1), srptool (1), psktool (1), certtool 
(1)
 _EOT_;
diff --git a/src/tests.c b/src/tests.c
index cbed468..0a327fe 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -1056,7 +1056,7 @@ test_certificate (gnutls_session_t session)
     return ret;
 
   printf ("\n");
-  print_cert_info (session, GNUTLS_CRT_PRINT_FULL);
+  print_cert_info (session, GNUTLS_CRT_PRINT_FULL, verbose);
 
   return TEST_SUCCEED;
 }


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]