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_11-81-gb934890


From: Simon Josefsson
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_3_0_11-81-gb934890
Date: Fri, 20 Jan 2012 13:23:08 +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=b9348908794d69aa0be3f29f3b32428c9f699907

The branch, master has been updated
       via  b9348908794d69aa0be3f29f3b32428c9f699907 (commit)
       via  9eed11206bc1c0cc6eb329d60f6fc464fc966b11 (commit)
       via  fb40782b072d8765a6e331c6c63c43798f4a8203 (commit)
       via  6dbde9ad3c9f60907a98fd202cc311c38acfb570 (commit)
      from  c5791654cc44e5398b3db10c4ddcc099a992a9c3 (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 b9348908794d69aa0be3f29f3b32428c9f699907
Author: Simon Josefsson <address@hidden>
Date:   Fri Jan 20 14:21:42 2012 +0100

    Generated.

commit 9eed11206bc1c0cc6eb329d60f6fc464fc966b11
Author: Simon Josefsson <address@hidden>
Date:   Fri Jan 20 13:57:00 2012 +0100

    Version 3.0.12.

commit fb40782b072d8765a6e331c6c63c43798f4a8203
Author: Simon Josefsson <address@hidden>
Date:   Fri Jan 20 13:56:26 2012 +0100

    Fix syntax-check rules.

commit 6dbde9ad3c9f60907a98fd202cc311c38acfb570
Author: Simon Josefsson <address@hidden>
Date:   Fri Jan 20 13:41:19 2012 +0100

    Add OCSP functionality.

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

Summary of changes:
 .gitignore                     |    8 +
 ChangeLog                      |  801 +++++++++++++++-
 NEWS                           |   52 +-
 cfg.mk                         |    2 +-
 configure.ac                   |    3 +-
 doc/Makefile.am                |   23 +-
 doc/cha-bib.texi               |   12 +
 doc/cha-cert-auth2.texi        |  362 +++++++
 doc/cha-functions.texi         |   10 +
 doc/cha-gtls-examples.texi     |   23 +
 doc/examples/Makefile.am       |    4 +
 doc/examples/ex-ocsp-client.c  |  193 ++++
 doc/examples/ex-ocsp-verify.c  |  153 +++
 doc/manpages/Makefile.am       |   46 +
 doc/reference/gnutls-docs.sgml |    1 +
 lib/includes/Makefile.am       |    2 +-
 lib/includes/gnutls/ocsp.h     |  254 +++++
 lib/libgnutls.map              |   32 +
 lib/pkix.asn                   |  109 ++
 lib/pkix_asn1_tab.c            |  105 ++-
 lib/x509/Makefile.am           |    4 +
 lib/x509/ocsp.c                | 2160 ++++++++++++++++++++++++++++++++++++++++
 lib/x509/ocsp_output.c         |  631 ++++++++++++
 m4/hooks.m4                    |   15 +
 po/POTFILES.in                 |    5 +-
 src/Makefile.am                |   13 +
 src/ocsptool-common.h          |   35 +
 src/ocsptool.c                 |  506 ++++++++++
 src/ocsptool.gaa               |   76 ++
 tests/Makefile.am              |    4 +
 tests/ocsp.c                   | 1480 +++++++++++++++++++++++++++
 31 files changed, 7110 insertions(+), 14 deletions(-)
 create mode 100644 doc/examples/ex-ocsp-client.c
 create mode 100644 doc/examples/ex-ocsp-verify.c
 create mode 100644 lib/includes/gnutls/ocsp.h
 create mode 100644 lib/x509/ocsp.c
 create mode 100644 lib/x509/ocsp_output.c
 create mode 100644 src/ocsptool-common.h
 create mode 100644 src/ocsptool.c
 create mode 100644 src/ocsptool.gaa
 create mode 100644 tests/ocsp.c

diff --git a/.gitignore b/.gitignore
index f11eec1..0940614 100644
--- a/.gitignore
+++ b/.gitignore
@@ -110,6 +110,7 @@ doc/latex/gnutls.lof
 doc/latex/gnutls.lot
 doc/manpages/Makefile
 doc/manpages/Makefile.in
+doc/ocsp-api.texi
 doc/pgp-api.texi
 doc/printlist
 doc/reference/Makefile
@@ -441,10 +442,14 @@ src/libcfg.la
 src/libcmd-certtool.la
 src/libcmd-cli-debug.la
 src/libcmd-cli.la
+src/libcmd-ocsp.la
 src/libcmd-p11tool.la
 src/libcmd-psk.la
 src/libcmd-serv.la
 src/libcmd-srp.la
+src/ocsptool
+src/ocsptool-gaa.c
+src/ocsptool-gaa.h
 src/p11tool
 src/psktool
 src/srptool
@@ -487,6 +492,7 @@ tests/moredn
 tests/mpi
 tests/netconf-psk
 tests/nul-in-x509-names
+tests/ocsp
 tests/openpgp-auth
 tests/openpgp-auth2
 tests/openpgp-certs/Makefile
@@ -541,6 +547,8 @@ tests/slow/keygen
 tests/slow/gendh
 doc/reference/*.bak
 doc/manpages/gnutls_*.3
+doc/examples/ex-ocsp-client
+doc/examples/ex-ocsp-verify
 doc/examples/ex-client-anon
 doc/examples/ex-client-dtls
 doc/examples/ex-client-x509
diff --git a/ChangeLog b/ChangeLog
index 33224e6..b294b4c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,802 @@
+2012-01-20  Simon Josefsson <address@hidden>
+
+       * NEWS, configure.ac: Version 3.0.12.
+
+2012-01-20  Simon Josefsson <address@hidden>
+
+       * cfg.mk, po/POTFILES.in: Fix syntax-check rules.
+
+2012-01-20  Simon Josefsson <address@hidden>
+
+       * .gitignore, NEWS, configure.ac, doc/Makefile.am,
+       doc/cha-bib.texi, doc/cha-cert-auth2.texi, doc/cha-functions.texi,
+       doc/cha-gtls-examples.texi, doc/examples/Makefile.am,
+       doc/examples/ex-ocsp-client.c, doc/examples/ex-ocsp-verify.c,
+       doc/manpages/Makefile.am, doc/reference/gnutls-docs.sgml,
+       lib/includes/Makefile.am, lib/includes/gnutls/ocsp.h,
+       lib/libgnutls.map, lib/pkix.asn, lib/pkix_asn1_tab.c,
+       lib/x509/Makefile.am, lib/x509/ocsp.c, lib/x509/ocsp_output.c,
+       m4/hooks.m4, src/Makefile.am, src/ocsptool-common.h,
+       src/ocsptool.c, src/ocsptool.gaa, tests/Makefile.am, tests/ocsp.c: 
+       Add OCSP functionality.
+
+2012-01-20  Simon Josefsson <address@hidden>
+
+       * lib/x509/verify-high.c, lib/x509/verify-high.h: Fix semantics of
+       (unused) _gnutls_trustlist_inlist.
+
+2012-01-20  Simon Josefsson <address@hidden>
+
+       * doc/manpages/Makefile.am: Bump copyright year on manpages.
+
+2012-01-20  Simon Josefsson <address@hidden>
+
+       * lib/x509/x509.c: Fix mem leak.
+
+2012-01-20  Simon Josefsson <address@hidden>
+
+       * doc/manpages/Makefile.am: Cosmetic improvement of build output.
+
+2012-01-19  Simon Josefsson <address@hidden>
+
+       * guile/tests/Makefile.am: Print detailed guile warnings (for
+       obsolete functions).
+
+2012-01-18  Simon Josefsson <address@hidden>
+
+       * doc/Makefile.am: Fix doc/enums/ generation to work with 'make
+       distcheck'.
+
+2012-01-18  Simon Josefsson <address@hidden>
+
+       * guile/pre-inst-guile.in: Fix builddir != srcdir builds.
+
+2012-01-18  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-gtls-app.texi: doc fix
+
+2012-01-18  Nikos Mavrogiannopoulos <address@hidden>
+
+       * NEWS, lib/gnutls_errors.c, lib/gnutls_priority.c, src/cli.c: 
+       GNUTLS_E_NO_PRIORITIES_WERE_SET is also returned by
+       gnutls_priority_set_* This allows to warn when an incomplete set of
+       priorities is specified.  Reported by Yaroslav Stavnichiy.
+
+2012-01-17  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/gnutls_errors.c, lib/gnutls_handshake.c,
+       lib/includes/gnutls/gnutls.h.in: introduced
+       GNUTLS_E_NO_PRIORITIES_WERE_SET.
+
+2012-01-15  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-gtls-app.texi, doc/texinfo.css: more documentation
+       updates.
+
+2012-01-15  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-internals.texi: added more information to internals''
+
+2012-01-15  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/printlist.c: better print supported algorithms.
+
+2012-01-17  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/examples/ex-client-x509.c: Added
+       gnutls_certificate_set_x509_key_file in a comment.
+
+2012-01-15  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/examples/ex-pkcs11-list.c, doc/examples/print-ciphersuites.c: 
+       added boilerplate
+
+2012-01-17  Ludovic Courtès <address@hidden>
+
+       * guile/pre-inst-guile.in: Fix $(srcdir) != $(builddir) for Guile.  Now 
that modules/gnutls.scm is generated, $(builddir) must be in the
+       search path.
+
+2012-01-16  Simon Josefsson <address@hidden>
+
+       * tests/ecdsa/ecdsa: Fix srcdir != builddir builds.  Tiny patch from 
Elias Pipping <address@hidden>.
+
+2012-01-16  Simon Josefsson <address@hidden>
+
+       * lib/includes/gnutls/gnutls.h.in, lib/nettle/ecc_mulmod.c: GTK-DOC
+       fixes.
+
+2012-01-16  Simon Josefsson <address@hidden>
+
+       * doc/manpages/Makefile.am: Generated.
+
+2012-01-16  Simon Josefsson <address@hidden>
+
+       * doc/cha-programs.texi: Fix sc_space_tab syntax-check nit.
+
+2012-01-16  Simon Josefsson <address@hidden>
+
+       * .clcopying, AUTHORS, cfg.mk, doc/Makefile.am,
+       doc/alert-printlist.c, doc/credentials/Makefile.am, doc/errcodes.c,
+       doc/examples/Makefile.am, doc/extract-guile-c-doc.scm,
+       doc/fdl-1.3.texi, doc/gpl-3.0.texi, doc/lgpl-2.1.texi,
+       doc/printlist.c, extra/Makefile.am, extra/gnutls_openssl.c,
+       extra/includes/Makefile.am, extra/includes/gnutls/openssl.h,
+       extra/openssl_compat.c, extra/openssl_compat.h, guile/Makefile.am,
+       guile/modules/Makefile.am, guile/modules/gnutls.in,
+       guile/modules/gnutls/build/enums.scm,
+       guile/modules/gnutls/build/priorities.scm,
+       guile/modules/gnutls/build/smobs.scm,
+       guile/modules/gnutls/build/utils.scm,
+       guile/modules/gnutls/extra.scm,
+       guile/modules/system/documentation/c-snarf.scm,
+       guile/modules/system/documentation/output.scm,
+       guile/pre-inst-guile.in, guile/src/errors.c, guile/src/utils.c,
+       guile/tests/anonymous-auth.scm, guile/tests/errors.scm,
+       guile/tests/openpgp-auth.scm, guile/tests/openpgp-keyring.scm,
+       guile/tests/openpgp-keys.scm, guile/tests/pkcs-import-export.scm,
+       guile/tests/session-record-port.scm, guile/tests/srp-base64.scm,
+       guile/tests/x509-auth.scm, guile/tests/x509-certificates.scm,
+       lib/auth/anon.c, lib/auth/anon_ecdh.c, lib/auth/dh_common.c,
+       lib/auth/dhe.c, lib/auth/dhe_psk.c, lib/auth/psk.c,
+       lib/auth/psk_passwd.c, lib/auth/rsa.c, lib/auth/rsa_export.c,
+       lib/auth/srp_passwd.c, lib/auth/srp_rsa.c, lib/auth/srp_sb64.c: 
+       Collapse and cleanup copyright information.
+
+2012-01-16  Simon Josefsson <address@hidden>
+
+       * .clcopying, AUTHORS, ChangeLog, ChangeLog.1, Makefile.am, NEWS,
+       README, README-alpha, THANKS, configure.ac, doc/Makefile.am,
+       doc/alert-printlist.c, doc/credentials/Makefile.am,
+       doc/cyclo/Makefile.am, doc/errcodes.c, doc/examples/Makefile.am,
+       doc/extract-guile-c-doc.scm, doc/fdl-1.3.texi,
+       doc/gnutls-guile.texi, doc/gnutls.texi, doc/gpl-3.0.texi,
+       doc/lgpl-2.1.texi, doc/manpages/Makefile.am, doc/printlist.c,
+       extra/Makefile.am, extra/gnutls_openssl.c,
+       extra/includes/Makefile.am, extra/includes/gnutls/openssl.h,
+       extra/openssl_compat.c, extra/openssl_compat.h, guile/Makefile.am,
+       guile/modules/Makefile.am, guile/modules/gnutls.in,
+       guile/modules/gnutls/build/enums.scm,
+       guile/modules/gnutls/build/priorities.scm,
+       guile/modules/gnutls/build/smobs.scm,
+       guile/modules/gnutls/build/tests.scm,
+       guile/modules/gnutls/build/utils.scm,
+       guile/modules/gnutls/extra.scm,
+       guile/modules/system/documentation/c-snarf.scm,
+       guile/modules/system/documentation/output.scm,
+       guile/pre-inst-guile.in, guile/src/Makefile.am, guile/src/core.c,
+       guile/src/errors.c, guile/src/errors.h,
+       guile/src/make-enum-header.scm, guile/src/make-enum-map.scm,
+       guile/src/make-session-priorities.scm,
+       guile/src/make-smob-header.scm, guile/src/make-smob-types.scm,
+       guile/src/utils.c, guile/src/utils.h, guile/tests/Makefile.am,
+       guile/tests/anonymous-auth.scm, guile/tests/errors.scm,
+       guile/tests/openpgp-auth.scm, guile/tests/openpgp-keyring.scm,
+       guile/tests/openpgp-keys.scm, guile/tests/pkcs-import-export.scm,
+       guile/tests/priorities.scm, guile/tests/session-record-port.scm,
+       guile/tests/srp-base64.scm, guile/tests/x509-auth.scm,
+       guile/tests/x509-certificates.scm, lib/Makefile.am,
+       lib/accelerated/Makefile.am, lib/accelerated/accelerated.c,
+       lib/accelerated/cryptodev.c, lib/accelerated/x86/Makefile.am,
+       lib/accelerated/x86/aes-gcm-padlock.c,
+       lib/accelerated/x86/aes-gcm-x86.c,
+       lib/accelerated/x86/aes-padlock.c, lib/accelerated/x86/aes-x86.c,
+       lib/accelerated/x86/asm-coff/cpuid-x86-64-coff.s,
+       lib/accelerated/x86/asm-coff/cpuid-x86-coff.s,
+       lib/accelerated/x86/asm/cpuid-x86-64.s,
+       lib/accelerated/x86/asm/cpuid-x86.s,
+       lib/accelerated/x86/hmac-padlock.c,
+       lib/accelerated/x86/sha-padlock.c, lib/accelerated/x86/x86.h,
+       lib/algorithms.h, lib/algorithms/Makefile.am,
+       lib/algorithms/cert_types.c, lib/algorithms/ciphers.c,
+       lib/algorithms/ciphersuites.c, lib/algorithms/ecc.c,
+       lib/algorithms/kx.c, lib/algorithms/mac.c,
+       lib/algorithms/protocols.c, lib/algorithms/publickey.c,
+       lib/algorithms/secparams.c, lib/algorithms/sign.c,
+       lib/auth/Makefile.am, lib/auth/anon.c, lib/auth/anon.h,
+       lib/auth/anon_ecdh.c, lib/auth/cert.c, lib/auth/cert.h,
+       lib/auth/dh_common.c, lib/auth/dh_common.h, lib/auth/dhe.c,
+       lib/auth/dhe_psk.c, lib/auth/ecdh_common.c, lib/auth/ecdh_common.h,
+       lib/auth/psk.c, lib/auth/psk.h, lib/auth/psk_passwd.c,
+       lib/auth/psk_passwd.h, lib/auth/rsa.c, lib/auth/rsa_export.c,
+       lib/auth/srp.c, lib/auth/srp.h, lib/auth/srp_passwd.c,
+       lib/auth/srp_passwd.h, lib/auth/srp_rsa.c, lib/auth/srp_sb64.c,
+       lib/crypto-api.c, lib/crypto-backend.c, lib/crypto-backend.h,
+       lib/crypto.h, lib/debug.c, lib/debug.h, lib/ext/Makefile.am,
+       lib/ext/cert_type.c, lib/ext/cert_type.h, lib/ext/ecc.c,
+       lib/ext/ecc.h, lib/ext/max_record.c, lib/ext/max_record.h,
+       lib/ext/safe_renegotiation.c, lib/ext/safe_renegotiation.h,
+       lib/ext/server_name.c, lib/ext/server_name.h,
+       lib/ext/session_ticket.c, lib/ext/session_ticket.h,
+       lib/ext/signature.c, lib/ext/signature.h, lib/ext/srp.c,
+       lib/ext/srp.h, lib/extras/Makefile.am, lib/gnutls.pc.in,
+       lib/gnutls_alert.c, lib/gnutls_anon_cred.c, lib/gnutls_auth.c,
+       lib/gnutls_auth.h, lib/gnutls_buffers.c, lib/gnutls_buffers.h,
+       lib/gnutls_cert.c, lib/gnutls_cipher.c, lib/gnutls_cipher.h,
+       lib/gnutls_cipher_int.c, lib/gnutls_cipher_int.h,
+       lib/gnutls_compress.c, lib/gnutls_compress.h,
+       lib/gnutls_constate.c, lib/gnutls_constate.h, lib/gnutls_datum.c,
+       lib/gnutls_datum.h, lib/gnutls_db.c, lib/gnutls_db.h,
+       lib/gnutls_dh.c, lib/gnutls_dh.h, lib/gnutls_dh_primes.c,
+       lib/gnutls_dtls.h, lib/gnutls_ecc.c, lib/gnutls_errors.c,
+       lib/gnutls_errors.h, lib/gnutls_extensions.c,
+       lib/gnutls_extensions.h, lib/gnutls_global.c, lib/gnutls_global.h,
+       lib/gnutls_handshake.c, lib/gnutls_handshake.h,
+       lib/gnutls_hash_int.c, lib/gnutls_hash_int.h, lib/gnutls_helper.c,
+       lib/gnutls_int.h, lib/gnutls_kx.c, lib/gnutls_kx.h,
+       lib/gnutls_mbuffers.h, lib/gnutls_mem.c, lib/gnutls_mem.h,
+       lib/gnutls_mpi.c, lib/gnutls_mpi.h, lib/gnutls_num.c,
+       lib/gnutls_num.h, lib/gnutls_pcert.c, lib/gnutls_pk.h,
+       lib/gnutls_priority.c, lib/gnutls_psk.c, lib/gnutls_record.c,
+       lib/gnutls_record.h, lib/gnutls_rsa_export.c,
+       lib/gnutls_rsa_export.h, lib/gnutls_session.c,
+       lib/gnutls_session_pack.c, lib/gnutls_session_pack.h,
+       lib/gnutls_sig.c, lib/gnutls_sig.h, lib/gnutls_srp.c,
+       lib/gnutls_srp.h, lib/gnutls_state.h, lib/gnutls_str.c,
+       lib/gnutls_str.h, lib/gnutls_str_array.h,
+       lib/gnutls_supplemental.c, lib/gnutls_supplemental.h,
+       lib/gnutls_ui.c, lib/gnutls_v2_compat.c, lib/gnutls_v2_compat.h,
+       lib/gnutls_x509.c, lib/gnutls_x509.h, lib/hash.c,
+       lib/includes/Makefile.am, lib/includes/gnutls/abstract.h,
+       lib/includes/gnutls/compat.h, lib/includes/gnutls/crypto.h,
+       lib/includes/gnutls/dtls.h, lib/includes/gnutls/gnutlsxx.h,
+       lib/includes/gnutls/openpgp.h, lib/includes/gnutls/pkcs11.h,
+       lib/includes/gnutls/pkcs12.h, lib/includes/gnutls/x509.h,
+       lib/libgnutls.map, lib/libgnutlsxx.map, lib/locks.c,
+       lib/minitasn1/Makefile.am, lib/minitasn1/coding.c,
+       lib/minitasn1/decoding.c, lib/minitasn1/element.c,
+       lib/minitasn1/element.h, lib/minitasn1/errors.c,
+       lib/minitasn1/gstr.c, lib/minitasn1/gstr.h, lib/minitasn1/int.h,
+       lib/minitasn1/libtasn1.h, lib/minitasn1/parser_aux.c,
+       lib/minitasn1/parser_aux.h, lib/minitasn1/structure.c,
+       lib/minitasn1/structure.h, lib/minitasn1/version.c,
+       lib/nettle/Makefile.am, lib/nettle/cipher.c, lib/nettle/ecc_free.c,
+       lib/nettle/ecc_make_key.c, lib/nettle/ecc_map.c,
+       lib/nettle/ecc_mulmod.c, lib/nettle/ecc_mulmod_timing.c,
+       lib/nettle/ecc_points.c, lib/nettle/ecc_projective_add_point.c,
+       lib/nettle/ecc_projective_check_point.c,
+       lib/nettle/ecc_projective_dbl_point_3.c,
+       lib/nettle/ecc_shared_secret.c, lib/nettle/ecc_sign_hash.c,
+       lib/nettle/ecc_verify_hash.c, lib/nettle/egd.c, lib/nettle/init.c,
+       lib/nettle/mac.c, lib/nettle/mpi.c, lib/nettle/pk.c,
+       lib/nettle/rnd.c, lib/opencdk/Makefile.am, lib/opencdk/armor.c,
+       lib/opencdk/context.h, lib/opencdk/filters.h, lib/opencdk/hash.c,
+       lib/opencdk/kbnode.c, lib/opencdk/keydb.c, lib/opencdk/literal.c,
+       lib/opencdk/main.h, lib/opencdk/misc.c, lib/opencdk/new-packet.c,
+       lib/opencdk/opencdk.h, lib/opencdk/packet.h, lib/opencdk/pubkey.c,
+       lib/opencdk/read-packet.c, lib/opencdk/seskey.c,
+       lib/opencdk/sig-check.c, lib/opencdk/stream.c,
+       lib/opencdk/stream.h, lib/opencdk/types.h,
+       lib/opencdk/write-packet.c, lib/openpgp/Makefile.am,
+       lib/openpgp/compat.c, lib/openpgp/extras.c,
+       lib/openpgp/gnutls_openpgp.c, lib/openpgp/output.c,
+       lib/openpgp/pgp.c, lib/openpgp/pgpverify.c, lib/openpgp/privkey.c,
+       lib/random.c, lib/random.h, lib/system.c, lib/system_override.c,
+       lib/x509/Makefile.am, lib/x509/common.c, lib/x509/common.h,
+       lib/x509/crl.c, lib/x509/crl_write.c, lib/x509/crq.c,
+       lib/x509/dn.c, lib/x509/extensions.c, lib/x509/key_decode.c,
+       lib/x509/key_encode.c, lib/x509/mpi.c, lib/x509/output.c,
+       lib/x509/pbkdf2-sha1.c, lib/x509/pkcs12.c, lib/x509/pkcs12_bag.c,
+       lib/x509/pkcs12_encr.c, lib/x509/pkcs7.c, lib/x509/privkey.c,
+       lib/x509/privkey_pkcs8.c, lib/x509/rfc2818_hostname.c,
+       lib/x509/sign.c, lib/x509/verify-high.c, lib/x509/verify-high.h,
+       lib/x509/x509_int.h, lib/x509/x509_write.c, lib/x509_b64.c,
+       lib/x509_b64.h, m4/gcc.m4, m4/guile.m4, m4/hooks.m4, po/cs.po.in,
+       po/de.po.in, po/fr.po.in, po/it.po.in, po/ms.po.in, po/nl.po.in,
+       po/pl.po.in, po/sv.po.in, po/uk.po.in, po/zh_CN.po.in,
+       src/Makefile.am, src/benchmark-cipher.c, src/benchmark-tls.c,
+       src/benchmark.c, src/certtool-cfg.c, src/certtool-common.c,
+       src/certtool.c, src/cli.c, src/common.c, src/crywrap/Makefile.am,
+       src/dh.c, src/p11common.c, src/p11tool.c, src/pkcs11.c, src/psk.c,
+       src/serv.c, src/srptool.c, src/tests.c, src/tls_test.c,
+       src/udp-serv.c, tests/Makefile.am, tests/anonself.c,
+       tests/certder.c, tests/certificate_set_x509_crl.c,
+       tests/certuniqueid.c, tests/chainverify.c, tests/crq_apis.c,
+       tests/crq_key_id.c, tests/cve-2008-4989.c, tests/cve-2009-1415.c,
+       tests/cve-2009-1416.c, tests/dhepskself.c, tests/dn.c, tests/dn2.c,
+       tests/dsa/Makefile.am, tests/dsa/testdsa, tests/ecdsa/Makefile.am,
+       tests/ecdsa/ecdsa, tests/gc.c, tests/hostname-check.c,
+       tests/infoaccess.c, tests/init_roundtrip.c,
+       tests/key-id/Makefile.am, tests/key-id/README, tests/key-id/key-id,
+       tests/mini-deflate.c, tests/mini-eagain-dtls.c,
+       tests/mini-eagain.c, tests/mini-x509-rehandshake.c,
+       tests/mini-x509.c, tests/mini.c, tests/moredn.c, tests/mpi.c,
+       tests/nist-pkits/pkits, tests/nist-pkits/pkits_crl,
+       tests/nist-pkits/pkits_crt, tests/nist-pkits/pkits_pkcs12,
+       tests/nist-pkits/pkits_smime, tests/nul-in-x509-names.c,
+       tests/openpgp-certs/Makefile.am, tests/openpgp-certs/testcerts,
+       tests/openpgp-certs/testselfsigs, tests/openpgp-keyring.c,
+       tests/openpgpself.c, tests/openssl.c, tests/parse_ca.c,
+       tests/pathlen/Makefile.am, tests/pathlen/pathlen,
+       tests/pgps2kgnu.c, tests/pkcs1-padding/Makefile.am,
+       tests/pkcs1-padding/pkcs1-pad, tests/pkcs12-decode/Makefile.am,
+       tests/pkcs12-decode/pkcs12, tests/pkcs12_encode.c,
+       tests/pkcs12_s2k.c, tests/pkcs12_s2k_pem.c,
+       tests/pkcs8-decode/Makefile.am, tests/pkcs8-decode/pkcs8,
+       tests/pskself.c, tests/resume.c, tests/rfc2253-escape-test,
+       tests/rng-fork.c, tests/rsa-encrypt-decrypt.c,
+       tests/rsa-md5-collision/Makefile.am,
+       tests/rsa-md5-collision/README,
+       tests/rsa-md5-collision/rsa-md5-collision,
+       tests/safe-renegotiation/Makefile.am,
+       tests/safe-renegotiation/srn0.c, tests/safe-renegotiation/srn1.c,
+       tests/safe-renegotiation/srn2.c, tests/safe-renegotiation/srn3.c,
+       tests/safe-renegotiation/srn4.c, tests/safe-renegotiation/srn5.c,
+       tests/scripts/Makefile.am, tests/set_pkcs12_cred.c,
+       tests/setcredcrash.c, tests/sha2/Makefile.am, tests/sha2/sha2,
+       tests/sha2/sha2-dsa, tests/simple.c, tests/slow/Makefile.am,
+       tests/slow/gendh.c, tests/slow/keygen.c, tests/suite/Makefile.am,
+       tests/suite/chain, tests/suite/eagain, tests/suite/testcompat,
+       tests/suite/testcompat-main, tests/suite/testsrn,
+       tests/suppressions.valgrind, tests/userid/Makefile.am,
+       tests/userid/userid, tests/userid/userid.pem, tests/utils.c,
+       tests/utils.h, tests/x509_altname.c, tests/x509cert-tl.c,
+       tests/x509cert.c, tests/x509dn.c, tests/x509self.c,
+       tests/x509sign-verify.c: Run 'make update-copyright'.
+
+2012-01-16  Simon Josefsson <address@hidden>
+
+       * cfg.mk: Ignore pkg.m4.  Copyright fixes.
+
+2012-01-14  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/gnutls_x509.c: improved doc
+
+2012-01-14  Simon Josefsson <address@hidden>
+
+       * lib/gnutls_pk.c: Fix memory leak.
+
+2012-01-14  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-cert-auth.texi, doc/cha-gtls-app.texi,
+       doc/cha-intro-tls.texi: properly spread authentication and
+       credentials doc.
+
+2012-01-14  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-gtls-app.texi: updated text
+
+2012-01-14  Nikos Mavrogiannopoulos <address@hidden>
+
+       * cfg.mk: no longer use texi2html. makeinfo --html has decent
+       output.
+
+2012-01-14  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/errcodes.c: print numeric error codes everywhere.
+
+2012-01-14  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-programs.texi: SECURE256 -> SECURE192
+
+2012-01-14  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/alert-printlist.c, doc/scripts/gdoc,
+       doc/scripts/split-texi.pl, doc/texinfo.css: updated css for better
+       html output.
+
+2012-01-14  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/includes/gnutls/gnutls.h.in: better indent
+       gnutls_certificate_set_x509_simple_pkcs12_file to allow them being
+       found by doc script.
+
+2012-01-14  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/gnutls.texi, doc/scripts/gdoc, doc/scripts/split-texi.pl: 
+       caption is set on enumerations in texinfo. Unfortunately they are
+       not visible to the pdf output due to a probable bug in texinfo.
+
+2012-01-14  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-cert-auth2.texi: Added pkcs12_simple function.
+
+2012-01-13  Nikos Mavrogiannopoulos <address@hidden>
+
+       * .gitignore: more files to ignore
+
+2012-01-13  Nikos Mavrogiannopoulos <address@hidden>
+
+       * gl/Makefile.am, gl/argp-parse.c, gl/inet_ntop.c,
+       gl/m4/gnulib-cache.m4, gl/m4/gnulib-comp.m4,
+       gl/m4/ld-version-script.m4, gl/m4/printf.m4, gl/m4/stdlib_h.m4,
+       gl/m4/usleep.m4, gl/select.c, gl/stdlib.in.h, gl/tests/Makefile.am,
+       gl/tests/ignore-value.h, gl/tests/pipe.c, gl/tests/test-init.sh,
+       gl/tests/test-usleep.c, gl/usleep.c, maint.mk, src/udp-serv.c: 
+       usleep() is no longer used.
+
+2012-01-12  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-intro-tls.texi, doc/errcodes.c: documentation updates
+
+2012-01-12  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/scripts/gdoc: improved gdoc output for function parameters.
+
+2012-01-12  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/algorithms/ciphers.c, lib/algorithms/mac.c,
+       lib/crypto-backend.h, lib/gnutls_cipher_int.c,
+       lib/gnutls_cipher_int.h, lib/gnutls_hash_int.c,
+       lib/gnutls_hash_int.h, lib/nettle/cipher.c, lib/nettle/mac.c: Only
+       list algorithms if they are implemented.
+
+2012-01-12  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/algorithms/ciphers.c: reordered ciphers to place on top the
+       most used.
+
+2012-01-12  Nikos Mavrogiannopoulos <address@hidden>
+
+       * .gitignore, doc/cha-gtls-app.texi, doc/cha-gtls-examples.texi,
+       doc/cha-programs.texi, doc/examples/Makefile.am,
+       doc/examples/print-ciphersuites.c: Documented ways to list the
+       enabled ciphersuites.
+
+2012-01-12  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-gtls-app.texi: updated
+
+2012-01-11  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-gtls-app.texi: documentation update
+
+2012-01-11  Nikos Mavrogiannopoulos <address@hidden>
+
+       * NEWS, lib/gnutls_handshake.c, lib/gnutls_int.h,
+       lib/gnutls_state.c, lib/includes/gnutls/gnutls.h.in,
+       lib/libgnutls.map: Added gnutls_session_resumption_requested().
+
+2012-01-11  Nikos Mavrogiannopoulos <address@hidden>
+
+       * NEWS: updated
+
+2012-01-11  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/auth/ecdh_common.c: avoid allocating a privkey param for the
+       public key.
+
+2012-01-11  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/nettle/ecc_shared_secret.c: corrected issue in ECDH key
+       generation.  This issue prevented an ECDH key that was smaller than
+       the prime from being correctly aligned.
+
+2012-01-11  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/gnutls_alert.c: better handle alert for
+       GNUTLS_E_PREMATURE_TERMINATION
+
+2012-01-11  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/gnutls_record.c: do not absorb error message
+
+2012-01-10  Nikos Mavrogiannopoulos <address@hidden>
+
+       * NEWS, lib/nettle/ecc_projective_check_point.c: Eliminated memory
+       leak in ecc_projective_check_point().
+
+2012-01-10  Nikos Mavrogiannopoulos <address@hidden>
+
+       * cross.mk: updated
+
+2012-01-10  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/includes/gnutls/x509.h, lib/x509/common.c, lib/x509/dn.c: 
+       gnutls_x509_dn_oid_name() was extended with a flags option that
+       accepts currently GNUTLS_X509_DN_OID_RETURN_OID or 0.
+
+2012-01-10  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-bib.texi, doc/cha-cert-auth.texi, doc/latex/gnutls.bib,
+       lib/includes/gnutls/compat.h, lib/x509/crl.c, lib/x509/dn.c,
+       lib/x509/x509.c: Added discussion of distinguished names.
+
+2012-01-10  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-cert-auth2.texi: describe gnutls_privkey_import_ext in
+       more detail.
+
+2012-01-09  Nikos Mavrogiannopoulos <address@hidden>
+
+       * NEWS, lib/includes/gnutls/x509.h, lib/libgnutls.map,
+       lib/x509/common.c, lib/x509/common.h, lib/x509/dn.c: Added
+       gnutls_x509_dn_oid_name().
+
+2012-01-09  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-cert-auth2.texi, doc/cha-gtls-app.texi: discuss the change
+       in Diffie-Hellman parameters.
+
+2012-01-09  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-gtls-app.texi, lib/gnutls_priority.c: Defined more
+       precisely the SECURE levels.
+
+2012-01-09  Nikos Mavrogiannopoulos <address@hidden>
+
+       * doc/cha-cert-auth2.texi, doc/cha-gtls-app.texi: updated for
+       pkg-config autoconf macro and added gnutls_pubkey_encrypt_data.
+
+2012-01-09  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/x509/x509.c: updated descriptions
+
+2012-01-09  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/x509/x509.c: removed not applicable comments.
+
+2012-01-08  Nikos Mavrogiannopoulos <address@hidden>
+
+       * NEWS, lib/gnutls_pubkey.c, lib/includes/gnutls/abstract.h,
+       lib/libgnutls.map, tests/Makefile.am, tests/rsa-encrypt-decrypt.c: 
+       Added gnutls_pubkey_encrypt_data().
+
+2012-01-08  Nikos Mavrogiannopoulos <address@hidden>
+
+       * configure.ac: more gcc warnings to ignore
+
+2012-01-08  Nikos Mavrogiannopoulos <address@hidden>
+
+       * src/serv.c, src/udp-serv.c, src/udp-serv.h: tcp and udp server are
+       now void functions.
+
+2012-01-08  Nikos Mavrogiannopoulos <address@hidden>
+
+       * NEWS, src/certtool.c: --outder option works for public keys.
+
+2012-01-08  Nikos Mavrogiannopoulos <address@hidden>
+
+       * NEWS, src/certtool.c: certtool --outder option now works for
+       private keys as well.
+
+2012-01-08  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/accelerated/x86/Makefile.am: removed trailing slash.
+
+2012-01-08  Nikos Mavrogiannopoulos <address@hidden>
+
+       * THANKS: updated thanks
+
+2012-01-08  Nikos Mavrogiannopoulos <address@hidden>
+
+       * tests/slow/Makefile.am: remove trailing slash.
+
+2012-01-08  Nikos Mavrogiannopoulos <address@hidden>
+
+       * GNUmakefile, build-aux/config.rpath, build-aux/pmccabe2html,
+       build-aux/snippet/arg-nonnull.h, build-aux/snippet/c++defs.h,
+       build-aux/snippet/warn-on-use.h, build-aux/useless-if-before-free,
+       build-aux/vc-list-files, gl/Makefile.am, gl/accept.c, gl/alloca.c,
+       gl/alloca.in.h, gl/alphasort.c, gl/argp-ba.c, gl/argp-eexst.c,
+       gl/argp-fmtstream.c, gl/argp-fmtstream.h, gl/argp-fs-xinl.c,
+       gl/argp-help.c, gl/argp-namefrob.h, gl/argp-parse.c, gl/argp-pin.c,
+       gl/argp-pv.c, gl/argp-pvh.c, gl/argp-xinl.c, gl/argp.h,
+       gl/arpa_inet.in.h, gl/asnprintf.c, gl/asprintf.c,
+       gl/basename-lgpl.c, gl/bind.c, gl/byteswap.in.h, gl/c-ctype.c,
+       gl/c-ctype.h, gl/close.c, gl/closedir.c, gl/connect.c,
+       gl/dirent-private.h, gl/dirent.in.h, gl/dirname-lgpl.c,
+       gl/dirname.h, gl/dosname.h, gl/errno.in.h, gl/error.c, gl/error.h,
+       gl/fd-hook.c, gl/fd-hook.h, gl/filename.h, gl/float+.h, gl/float.c,
+       gl/float.in.h, gl/fpucw.h, gl/frexp.c, gl/frexpl.c, gl/fseek.c,
+       gl/fseeko.c, gl/fseterr.c, gl/fseterr.h, gl/fstat.c, gl/ftell.c,
+       gl/ftello.c, gl/gai_strerror.c, gl/getaddrinfo.c, gl/getdelim.c,
+       gl/getline.c, gl/getopt.c, gl/getopt.in.h, gl/getopt1.c,
+       gl/getopt_int.h, gl/getpass.c, gl/getpass.h, gl/getpeername.c,
+       gl/getsubopt.c, gl/gettext.h, gl/gettime.c, gl/gettimeofday.c,
+       gl/inet_ntop.c, gl/inet_pton.c, gl/intprops.h, gl/isnan.c,
+       gl/isnand-nolibm.h, gl/isnand.c, gl/isnanf-nolibm.h, gl/isnanf.c,
+       gl/isnanl-nolibm.h, gl/isnanl.c, gl/itold.c, gl/listen.c,
+       gl/lseek.c, gl/m4/00gnulib.m4, gl/m4/alloca.m4, gl/m4/alphasort.m4,
+       gl/m4/argp.m4, gl/m4/arpa_inet_h.m4, gl/m4/byteswap.m4,
+       gl/m4/clock_time.m4, gl/m4/close.m4, gl/m4/closedir.m4,
+       gl/m4/codeset.m4, gl/m4/dirent_h.m4, gl/m4/dirname.m4,
+       gl/m4/double-slash-root.m4, gl/m4/dup2.m4, gl/m4/eealloc.m4,
+       gl/m4/environ.m4, gl/m4/errno_h.m4, gl/m4/error.m4,
+       gl/m4/exponentd.m4, gl/m4/exponentf.m4, gl/m4/exponentl.m4,
+       gl/m4/extensions.m4, gl/m4/fcntl-o.m4, gl/m4/fcntl_h.m4,
+       gl/m4/fdopen.m4, gl/m4/float_h.m4, gl/m4/fpieee.m4, gl/m4/frexp.m4,
+       gl/m4/frexpl.m4, gl/m4/fseek.m4, gl/m4/fseeko.m4, gl/m4/fstat.m4,
+       gl/m4/ftell.m4, gl/m4/ftello.m4, gl/m4/ftruncate.m4, gl/m4/func.m4,
+       gl/m4/getaddrinfo.m4, gl/m4/getcwd.m4, gl/m4/getdelim.m4,
+       gl/m4/getline.m4, gl/m4/getopt.m4, gl/m4/getpagesize.m4,
+       gl/m4/getpass.m4, gl/m4/getsubopt.m4, gl/m4/gettext.m4,
+       gl/m4/gettime.m4, gl/m4/gettimeofday.m4, gl/m4/glibc2.m4,
+       gl/m4/glibc21.m4, gl/m4/gnulib-cache.m4, gl/m4/gnulib-common.m4,
+       gl/m4/gnulib-comp.m4, gl/m4/gnulib-tool.m4, gl/m4/hostent.m4,
+       gl/m4/iconv.m4, gl/m4/include_next.m4, gl/m4/inet_ntop.m4,
+       gl/m4/inet_pton.m4, gl/m4/intdiv0.m4, gl/m4/intl.m4,
+       gl/m4/intldir.m4, gl/m4/intlmacosx.m4, gl/m4/intmax.m4,
+       gl/m4/intmax_t.m4, gl/m4/inttypes-pri.m4, gl/m4/inttypes.m4,
+       gl/m4/inttypes_h.m4, gl/m4/ioctl.m4, gl/m4/isnand.m4,
+       gl/m4/isnanf.m4, gl/m4/isnanl.m4, gl/m4/largefile.m4,
+       gl/m4/lcmessage.m4, gl/m4/ld-output-def.m4,
+       gl/m4/ld-version-script.m4, gl/m4/ldexpl.m4, gl/m4/lib-ld.m4,
+       gl/m4/lib-link.m4, gl/m4/lib-prefix.m4, gl/m4/lock.m4,
+       gl/m4/longlong.m4, gl/m4/lseek.m4, gl/m4/lstat.m4, gl/m4/malloc.m4,
+       gl/m4/malloca.m4, gl/m4/manywarnings.m4, gl/m4/math_h.m4,
+       gl/m4/memchr.m4, gl/m4/memmem.m4, gl/m4/mempcpy.m4,
+       gl/m4/minmax.m4, gl/m4/mmap-anon.m4, gl/m4/mode_t.m4,
+       gl/m4/msvc-inval.m4, gl/m4/msvc-nothrow.m4, gl/m4/multiarch.m4,
+       gl/m4/netdb_h.m4, gl/m4/netinet_in_h.m4, gl/m4/nls.m4,
+       gl/m4/nocrash.m4, gl/m4/open.m4, gl/m4/opendir.m4,
+       gl/m4/pathmax.m4, gl/m4/perror.m4, gl/m4/pipe.m4, gl/m4/po.m4,
+       gl/m4/printf-frexp.m4, gl/m4/printf-frexpl.m4,
+       gl/m4/printf-posix.m4, gl/m4/printf.m4, gl/m4/progtest.m4,
+       gl/m4/putenv.m4, gl/m4/rawmemchr.m4, gl/m4/read-file.m4,
+       gl/m4/readdir.m4, gl/m4/realloc.m4, gl/m4/scandir.m4,
+       gl/m4/select.m4, gl/m4/servent.m4, gl/m4/setenv.m4,
+       gl/m4/signal_h.m4, gl/m4/signbit.m4, gl/m4/size_max.m4,
+       gl/m4/sleep.m4, gl/m4/snprintf.m4, gl/m4/socketlib.m4,
+       gl/m4/sockets.m4, gl/m4/socklen.m4, gl/m4/sockpfaf.m4,
+       gl/m4/ssize_t.m4, gl/m4/stat.m4, gl/m4/stdalign.m4,
+       gl/m4/stdarg.m4, gl/m4/stdbool.m4, gl/m4/stddef_h.m4,
+       gl/m4/stdint.m4, gl/m4/stdint_h.m4, gl/m4/stdio_h.m4,
+       gl/m4/stdlib_h.m4, gl/m4/strcase.m4, gl/m4/strchrnul.m4,
+       gl/m4/strdup.m4, gl/m4/strerror.m4, gl/m4/strerror_r.m4,
+       gl/m4/string_h.m4, gl/m4/strings_h.m4, gl/m4/strndup.m4,
+       gl/m4/strnlen.m4, gl/m4/strverscmp.m4, gl/m4/symlink.m4,
+       gl/m4/sys_ioctl_h.m4, gl/m4/sys_select_h.m4, gl/m4/sys_socket_h.m4,
+       gl/m4/sys_stat_h.m4, gl/m4/sys_time_h.m4, gl/m4/sys_types_h.m4,
+       gl/m4/sys_uio_h.m4, gl/m4/sysexits.m4, gl/m4/thread.m4,
+       gl/m4/threadlib.m4, gl/m4/time_h.m4, gl/m4/time_r.m4,
+       gl/m4/timespec.m4, gl/m4/uintmax_t.m4, gl/m4/ungetc.m4,
+       gl/m4/unistd_h.m4, gl/m4/usleep.m4, gl/m4/valgrind-tests.m4,
+       gl/m4/vasnprintf.m4, gl/m4/vasprintf.m4, gl/m4/version-etc.m4,
+       gl/m4/vfprintf-posix.m4, gl/m4/visibility.m4,
+       gl/m4/vprintf-posix.m4, gl/m4/vsnprintf.m4, gl/m4/warn-on-use.m4,
+       gl/m4/warnings.m4, gl/m4/wchar_h.m4, gl/m4/wchar_t.m4,
+       gl/m4/wint_t.m4, gl/m4/xsize.m4, gl/m4/yield.m4, gl/malloc.c,
+       gl/math.in.h, gl/memchr.c, gl/memmem.c, gl/mempcpy.c, gl/minmax.h,
+       gl/msvc-inval.c, gl/msvc-inval.h, gl/msvc-nothrow.c,
+       gl/msvc-nothrow.h, gl/netdb.in.h, gl/netinet_in.in.h, gl/opendir.c,
+       gl/override/m4/valgrind-tests.m4.diff, gl/printf-args.c,
+       gl/printf-args.h, gl/printf-frexp.c, gl/printf-frexp.h,
+       gl/printf-frexpl.c, gl/printf-frexpl.h, gl/printf-parse.c,
+       gl/printf-parse.h, gl/progname.c, gl/progname.h, gl/rawmemchr.c,
+       gl/read-file.c, gl/read-file.h, gl/readdir.c, gl/realloc.c,
+       gl/recv.c, gl/recvfrom.c, gl/scandir.c, gl/select.c, gl/send.c,
+       gl/sendto.c, gl/setsockopt.c, gl/shutdown.c, gl/signal.in.h,
+       gl/signbitd.c, gl/signbitf.c, gl/signbitl.c, gl/size_max.h,
+       gl/sleep.c, gl/snprintf.c, gl/socket.c, gl/sockets.c, gl/sockets.h,
+       gl/stdalign.in.h, gl/stdarg.in.h, gl/stdbool.in.h, gl/stddef.in.h,
+       gl/stdint.in.h, gl/stdio-impl.h, gl/stdio.in.h, gl/stdlib.in.h,
+       gl/str-two-way.h, gl/strcasecmp.c, gl/strchrnul.c, gl/strdup.c,
+       gl/strerror-override.c, gl/strerror-override.h, gl/strerror.c,
+       gl/string.in.h, gl/strings.in.h, gl/stripslash.c, gl/strncasecmp.c,
+       gl/strndup.c, gl/strnlen.c, gl/strverscmp.c, gl/sys_select.in.h,
+       gl/sys_socket.in.h, gl/sys_stat.in.h, gl/sys_time.in.h,
+       gl/sys_types.in.h, gl/sys_uio.in.h, gl/sysexits.in.h,
+       gl/tests/Makefile.am, gl/tests/binary-io.h, gl/tests/dup2.c,
+       gl/tests/fcntl.in.h, gl/tests/fdopen.c, gl/tests/getcwd-lgpl.c,
+       gl/tests/getpagesize.c, gl/tests/glthread/lock.c,
+       gl/tests/glthread/lock.h, gl/tests/glthread/thread.c,
+       gl/tests/glthread/thread.h, gl/tests/glthread/threadlib.c,
+       gl/tests/glthread/yield.h, gl/tests/ignore-value.h,
+       gl/tests/infinity.h, gl/tests/init.sh, gl/tests/inttypes.in.h,
+       gl/tests/ioctl.c, gl/tests/lstat.c, gl/tests/macros.h,
+       gl/tests/malloca.c, gl/tests/malloca.h, gl/tests/minus-zero.h,
+       gl/tests/nan.h, gl/tests/open.c, gl/tests/pathmax.h,
+       gl/tests/perror.c, gl/tests/pipe.c, gl/tests/putenv.c,
+       gl/tests/same-inode.h, gl/tests/setenv.c, gl/tests/signature.h,
+       gl/tests/stat.c, gl/tests/strerror_r.c, gl/tests/symlink.c,
+       gl/tests/sys_ioctl.in.h, gl/tests/test-accept.c,
+       gl/tests/test-alloca-opt.c, gl/tests/test-argp-2.sh,
+       gl/tests/test-argp.c, gl/tests/test-arpa_inet.c,
+       gl/tests/test-binary-io.c, gl/tests/test-binary-io.sh,
+       gl/tests/test-bind.c, gl/tests/test-byteswap.c,
+       gl/tests/test-c-ctype.c, gl/tests/test-close.c,
+       gl/tests/test-connect.c, gl/tests/test-dirent.c,
+       gl/tests/test-dup2.c, gl/tests/test-environ.c,
+       gl/tests/test-errno.c, gl/tests/test-fcntl-h.c,
+       gl/tests/test-fdopen.c, gl/tests/test-fgetc.c,
+       gl/tests/test-float.c, gl/tests/test-fprintf-posix.h,
+       gl/tests/test-fputc.c, gl/tests/test-fread.c,
+       gl/tests/test-frexp.c, gl/tests/test-frexpl.c,
+       gl/tests/test-fseek.c, gl/tests/test-fseeko.c,
+       gl/tests/test-fseeko3.c, gl/tests/test-fseeko4.c,
+       gl/tests/test-fseterr.c, gl/tests/test-fstat.c,
+       gl/tests/test-ftell.c, gl/tests/test-ftell3.c,
+       gl/tests/test-ftello.c, gl/tests/test-ftello3.c,
+       gl/tests/test-ftello4.c, gl/tests/test-ftruncate.c,
+       gl/tests/test-func.c, gl/tests/test-fwrite.c,
+       gl/tests/test-getaddrinfo.c, gl/tests/test-getcwd-lgpl.c,
+       gl/tests/test-getdelim.c, gl/tests/test-getline.c,
+       gl/tests/test-getopt.c, gl/tests/test-getopt.h,
+       gl/tests/test-getopt_long.h, gl/tests/test-getpeername.c,
+       gl/tests/test-gettimeofday.c, gl/tests/test-ignore-value.c,
+       gl/tests/test-inet_ntop.c, gl/tests/test-inet_pton.c,
+       gl/tests/test-init.sh, gl/tests/test-intprops.c,
+       gl/tests/test-inttypes.c, gl/tests/test-ioctl.c,
+       gl/tests/test-isnand-nolibm.c, gl/tests/test-isnand.h,
+       gl/tests/test-isnanf-nolibm.c, gl/tests/test-isnanf.h,
+       gl/tests/test-isnanl-nolibm.c, gl/tests/test-isnanl.h,
+       gl/tests/test-listen.c, gl/tests/test-lock.c,
+       gl/tests/test-lstat.c, gl/tests/test-lstat.h,
+       gl/tests/test-malloc-gnu.c, gl/tests/test-malloca.c,
+       gl/tests/test-math.c, gl/tests/test-memchr.c,
+       gl/tests/test-netdb.c, gl/tests/test-netinet_in.c,
+       gl/tests/test-open.c, gl/tests/test-open.h,
+       gl/tests/test-pathmax.c, gl/tests/test-perror.c,
+       gl/tests/test-perror2.c, gl/tests/test-pipe.c,
+       gl/tests/test-printf-frexp.c, gl/tests/test-printf-frexpl.c,
+       gl/tests/test-printf-posix.h, gl/tests/test-rawmemchr.c,
+       gl/tests/test-read-file.c, gl/tests/test-recv.c,
+       gl/tests/test-recvfrom.c, gl/tests/test-select-fd.c,
+       gl/tests/test-select-stdin.c, gl/tests/test-select.c,
+       gl/tests/test-select.h, gl/tests/test-send.c,
+       gl/tests/test-sendto.c, gl/tests/test-setenv.c,
+       gl/tests/test-setsockopt.c, gl/tests/test-shutdown.c,
+       gl/tests/test-signal-h.c, gl/tests/test-signbit.c,
+       gl/tests/test-sleep.c, gl/tests/test-snprintf.c,
+       gl/tests/test-sockets.c, gl/tests/test-stat.c,
+       gl/tests/test-stat.h, gl/tests/test-stdalign.c,
+       gl/tests/test-stdbool.c, gl/tests/test-stddef.c,
+       gl/tests/test-stdint.c, gl/tests/test-stdio.c,
+       gl/tests/test-stdlib.c, gl/tests/test-strchrnul.c,
+       gl/tests/test-strerror.c, gl/tests/test-strerror_r.c,
+       gl/tests/test-string.c, gl/tests/test-strings.c,
+       gl/tests/test-strnlen.c, gl/tests/test-strverscmp.c,
+       gl/tests/test-symlink.c, gl/tests/test-symlink.h,
+       gl/tests/test-sys_ioctl.c, gl/tests/test-sys_select.c,
+       gl/tests/test-sys_socket.c, gl/tests/test-sys_stat.c,
+       gl/tests/test-sys_time.c, gl/tests/test-sys_types.c,
+       gl/tests/test-sys_uio.c, gl/tests/test-sys_wait.h,
+       gl/tests/test-sysexits.c, gl/tests/test-thread_create.c,
+       gl/tests/test-thread_self.c, gl/tests/test-time.c,
+       gl/tests/test-u64.c, gl/tests/test-unistd.c,
+       gl/tests/test-unsetenv.c, gl/tests/test-usleep.c,
+       gl/tests/test-vasnprintf.c, gl/tests/test-vasprintf.c,
+       gl/tests/test-vc-list-files-cvs.sh,
+       gl/tests/test-vc-list-files-git.sh, gl/tests/test-verify.c,
+       gl/tests/test-version-etc.c, gl/tests/test-version-etc.sh,
+       gl/tests/test-vfprintf-posix.c, gl/tests/test-vprintf-posix.c,
+       gl/tests/test-vsnprintf.c, gl/tests/test-wchar.c,
+       gl/tests/unsetenv.c, gl/tests/w32sock.h, gl/tests/zerosize-ptr.h,
+       gl/time.in.h, gl/time_r.c, gl/timespec.h, gl/u64.h, gl/unistd.in.h,
+       gl/usleep.c, gl/vasnprintf.c, gl/vasnprintf.h, gl/vasprintf.c,
+       gl/verify.h, gl/version-etc-fsf.c, gl/version-etc.c,
+       gl/version-etc.h, gl/vfprintf.c, gl/vprintf.c, gl/vsnprintf.c,
+       gl/w32sock.h, gl/wchar.in.h, gl/xsize.h, maint.mk: Updated gnulib
+       and added usleep and getaddrinfo modules.
+
+2012-01-08  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/x509/output.c: Authority information access information ->
+       Authority information access
+
+2012-01-07  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/auth/cert.c, lib/auth/cert.h, lib/auth/dhe.c, lib/auth/rsa.c,
+       lib/auth/rsa_export.c, lib/auth/srp_rsa.c: 
+       _gnutls_proc_cert_client_certificate and
+       _gnutls_proc_cert_server_certificate renamed to
+       _gnutls_proc_certificate.
+
+2012-01-07  Nikos Mavrogiannopoulos <address@hidden>
+
+       * NEWS: updated news
+
+2012-01-06  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/gnutls_dh_primes.c: gnutls_dh_params_cpy() copies the
+       src->q_bits.
+
+2012-01-06  Nikos Mavrogiannopoulos <address@hidden>
+
+       * tests/slow/gendh.c: properly deinitialize.
+
+2012-01-06  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/nettle/mpi.c: corrected leak in DH parameter generation.
+
+2012-01-06  Nikos Mavrogiannopoulos <address@hidden>
+
+       * ChangeLog: updated changelog
+
+2012-01-06  Nikos Mavrogiannopoulos <address@hidden>
+
+       * lib/nettle/mpi.c: removed old comment
+
 2012-01-06  Nikos Mavrogiannopoulos <address@hidden>
 
        * ChangeLog, NEWS: updated changelog and news for release
@@ -9744,7 +10543,7 @@
 
        -----
 
-       Copyright (C) 2005-2010, 2012 Free Software Foundation, Inc.
+       Copyright (C) 2005-2012 Free Software Foundation, Inc.
 
        Copying and distribution of this file, with or without
        modification, are permitted provided the copyright notice
diff --git a/NEWS b/NEWS
index 76fa241..bd772e0 100644
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,21 @@ GnuTLS NEWS -- History of user-visible changes.                
-*- outline -*-
 Copyright (C) 2000-2012 Free Software Foundation, Inc.
 See the end for copying conditions.
 
-* Version 3.0.12 (unreleased)
+* Version 3.0.12 (released 2012-01-20)
+
+** libgnutls: Added OCSP support.
+There is a new header file gnutls/ocsp.h and a set of new functions
+under the gnutls_ocsp namespace.  Currently the functionality provided
+is to parse and extract information from OCSP requests/responses, to
+generate OCSP requests and to verify OCSP responses.  See the manual
+for more information.  Run ./configure with --disable-ocsp to build
+GnuTLS without OCSP support.
+
+This work was sponsored by Smoothwall <http://smoothwall.net/>.
+
+** ocsptool: Added new command line tool.
+The tool can parse OCSP request/responses, generate OCSP requests and
+verify OCSP responses.  See the manual for more information.
 
 ** certtool: --outder option now works for private
 and public keys as well.
@@ -24,6 +38,42 @@ return a descriptive name of a DN OID.
 gnutls_pubkey_encrypt_data: Added
 gnutls_x509_dn_oid_name: Added
 gnutls_session_resumption_requested: Added
+gnutls/ocsp.h: Added new header file.
+gnutls_ocsp_print_formats_t: Added new type.
+gnutls_ocsp_resp_status_t: Added new type.
+gnutls_ocsp_cert_status_t: Added new type.
+gnutls_x509_crl_reason_t: Added new type.
+gnutls_ocsp_req_add_cert: Added.
+gnutls_ocsp_req_add_cert_id: Added.
+gnutls_ocsp_req_deinit: Added.
+gnutls_ocsp_req_export: Added.
+gnutls_ocsp_req_get_cert_id: Added.
+gnutls_ocsp_req_get_extension: Added.
+gnutls_ocsp_req_get_nonce: Added.
+gnutls_ocsp_req_get_version: Added.
+gnutls_ocsp_req_import: Added.
+gnutls_ocsp_req_init: Added.
+gnutls_ocsp_req_print: Added.
+gnutls_ocsp_req_randomize_nonce: Added.
+gnutls_ocsp_req_set_extension: Added.
+gnutls_ocsp_req_set_nonce: Added.
+gnutls_ocsp_resp_deinit: Added.
+gnutls_ocsp_resp_export: Added.
+gnutls_ocsp_resp_get_certs: Added.
+gnutls_ocsp_resp_get_extension: Added.
+gnutls_ocsp_resp_get_nonce: Added.
+gnutls_ocsp_resp_get_produced: Added.
+gnutls_ocsp_resp_get_responder: Added.
+gnutls_ocsp_resp_get_response: Added.
+gnutls_ocsp_resp_get_signature: Added.
+gnutls_ocsp_resp_get_signature_algorithm: Added.
+gnutls_ocsp_resp_get_single: Added.
+gnutls_ocsp_resp_get_status: Added.
+gnutls_ocsp_resp_get_version: Added.
+gnutls_ocsp_resp_import: Added.
+gnutls_ocsp_resp_init: Added.
+gnutls_ocsp_resp_print: Added.
+gnutls_ocsp_resp_verify: Added.
 
 * Version 3.0.11 (released 2012-01-06)
 
diff --git a/cfg.mk b/cfg.mk
index 3ad361c..82310f8 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -46,7 +46,7 @@ update-copyright-env = UPDATE_COPYRIGHT_USE_INTERVALS=1
 # Explicit syntax-check exceptions.
 exclude_file_name_regexp--sc_cast_of_alloca_return_value = 
^guile/modules/gnutls/build/priorities.scm|guile/src/core.c$$
 exclude_file_name_regexp--sc_error_message_period = ^src/crywrap/crywrap.c$$
-exclude_file_name_regexp--sc_error_message_uppercase = 
^doc/examples/ex-cxx.cpp|guile/src/core.c|src/certtool.c|src/crywrap/crywrap.c|tests/pkcs12_encode.c$$
+exclude_file_name_regexp--sc_error_message_uppercase = 
^doc/examples/ex-cxx.cpp|guile/src/core.c|src/certtool.c|src/ocsptool.c|src/crywrap/crywrap.c|tests/pkcs12_encode.c$$
 exclude_file_name_regexp--sc_file_system = ^doc/doxygen/Doxyfile
 exclude_file_name_regexp--sc_prohibit_cvs_keyword = ^lib/nettle/.*$$
 exclude_file_name_regexp--sc_prohibit_undesirable_word_seq = 
^tests/nist-pkits/gnutls-nist-tests.html$$
diff --git a/configure.ac b/configure.ac
index dbfb779..f36e75b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure 
script.
 # USA
 
 AC_PREREQ(2.61)
-AC_INIT([GnuTLS], [3.0.11], address@hidden)
+AC_INIT([GnuTLS], [3.0.12], address@hidden)
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_MACRO_DIR([m4])
 
@@ -529,4 +529,5 @@ AC_MSG_NOTICE([summary of build options:
   Crypto library:   $cryptolib
   PKCS#11 support:  $with_p11_kit
   crywrap app:      $libidn
+  OCSP support:     $ac_enable_ocsp
 ])
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 4fc27c4..0d05b88 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -88,13 +88,13 @@ MAINTAINERCLEANFILES =
 
 # Generated texinfos.
 
-gnutls_TEXINFOS += gnutls-api.texi \
-       x509-api.texi pgp-api.texi pkcs12-api.texi pkcs11-api.texi \
-       abstract-api.texi compat-api.texi dtls-api.texi crypto-api.texi
+gnutls_TEXINFOS += gnutls-api.texi x509-api.texi pgp-api.texi          \
+       pkcs12-api.texi pkcs11-api.texi abstract-api.texi               \
+       compat-api.texi dtls-api.texi crypto-api.texi ocsp-api.texi
 
-MAINTAINERCLEANFILES += gnutls-api.texi \
-       x509-api.texi pgp-api.texi pkcs12-api.texi pkcs11-api.texi \
-       abstract-api.texi compat-api.texi dtls-api.texi crypto-api.texi
+MAINTAINERCLEANFILES += gnutls-api.texi x509-api.texi pgp-api.texi     \
+       pkcs12-api.texi pkcs11-api.texi abstract-api.texi               \
+       compat-api.texi dtls-api.texi crypto-api.texi ocsp-api.texi
 
 gnutls-api.texi: $(top_srcdir)/lib/includes/gnutls/gnutls.h.in
        echo "" > address@hidden
@@ -196,6 +196,17 @@ crypto-api.texi: $(top_srcdir)/lib/includes/gnutls/crypto.h
        done
        mv -f address@hidden $@
 
+ocsp-api.texi: $(top_srcdir)/lib/includes/gnutls/ocsp.h
+       echo "" > address@hidden
+       for i in `$(top_srcdir)/doc/scripts/getfuncs.pl 
<$(top_srcdir)/lib/includes/gnutls/ocsp.h|sort|uniq`; do \
+               echo -n "Creating documentation for file $$i... " && \
+               $(srcdir)/scripts/gdoc -texinfo \
+                       -function $$i \
+                       $(top_srcdir)/lib/*.c $(top_srcdir)/lib/*/*.c >> 
address@hidden 2>/dev/null && \
+               echo "ok"; \
+       done
+       mv -f address@hidden $@
+
 # Generated texinfos.
 # for some reason it does not work when cross compiling
 if !WINDOWS
diff --git a/doc/cha-bib.texi b/doc/cha-bib.texi
index 40848db..c88d9f6 100644
--- a/doc/cha-bib.texi
+++ b/doc/cha-bib.texi
@@ -181,4 +181,16 @@ John Wiley \& Sons, Inc., 2001.
 M. Mathis, J. Heffner, "Packetization Layer Path MTU Discovery", March 2007,
 available from @url{http://www.ietf.org/rfc/rfc4821.txt}.
 
address@hidden @anchor{RFC2560}[RFC2560]
+M. Myers et al, "X.509 Internet Public Key Infrastructure Online
+Certificate Status Protocol - OCSP", June 1999, Available from
address@hidden://www.ietf.org/rfc/rfc2560.txt}.
+
address@hidden @anchor{RIVESTCRL}[RIVESTCRL]
+R. L. Rivest, "Can We Eliminate Certificate Revocation Lists?",
+Proceedings of Financial Cryptography '98; Springer Lecture Notes in
+Computer Science No. 1465 (Rafael Hirschfeld, ed.), February 1998),
+pages 178--183, available from
address@hidden://people.csail.mit.edu/rivest/Rivest-CanWeEliminateCertificateRevocationLists.pdf}.
+
 @end table
diff --git a/doc/cha-cert-auth2.texi b/doc/cha-cert-auth2.texi
index 01ac7b5..27caf49 100644
--- a/doc/cha-cert-auth2.texi
+++ b/doc/cha-cert-auth2.texi
@@ -10,8 +10,10 @@ structures, etc., are discussed in this chapter.
 @menu
 * PKCS 10 certificate requests::
 * PKIX certificate revocation lists::
+* OCSP certificate status checking::
 * Managing encrypted keys::
 * The certtool application::
+* The ocsptool application::
 * Smart cards and HSMs::
 * Abstract key types::
 @end menu
@@ -116,6 +118,177 @@ CRL number extension and the authority key identifier.
 
 @showfuncB{gnutls_x509_crl_set_number,gnutls_x509_crl_set_authority_key_id}
 
address@hidden OCSP certificate status checking
address@hidden @acronym{OCSP} certificate status checking
address@hidden certificate status
address@hidden Online Certificate Status Protocol
address@hidden OCSP
+
+Certificates may be revoked before their expiration time has been
+reached.  There are several reasons for revoking certificates, but a
+typical situation is when the private key associated with a
+certificate has been compromised.  Traditionally, Certificate
+Revocation Lists (CRLs) have been used by application to implement
+revocation checking, however several disadvantages with CRLs have been
+identified, see for example @xcite{RIVESTCRL}.
+
+The Online Certificate Status Protocol (@acronym{OCSP}) is a widely
+implemented protocol to perform certificate (revocation) status
+checking.  @xcite{RFC2560}.  An application that wish to verify the
+identity of a peer will verify the certificate against a set of
+trusted certificates and then check whether the certificate is listed
+in a CRL and/or perform an OCSP check for the certificate.
+
+Before performing the OCSP query, the application will need to figure
+out the address of the OCSP server.  The OCSP server address can be
+provided by the local user in manual configuration.  The address can
+also be provided in the certificate that is being checked.  There is
+an extension field called the Authority Information Access (AIA) which
+has an access method called @code{id-ad-ocsp} that holds the location
+of the OCSP responder.  There is a function for extracting this
+information from a certificate.
+
address@hidden
+
+There are several functions in GnuTLS for creating and manipulating
+OCSP requests and responses.  The general idea is that a client
+application create an OCSP request object, store some information
+about the certificate to check in the request, and then export the
+request in DER format.  The request will then need to be sent to the
+OCSP responder, which needs to be done by the application (GnuTLS does
+not send and receive OCSP packets).  Normally an OCSP response is
+received that the application will need to import into an OCSP
+response object.  The digital signature in the OCSP response needs to
+be verified against a set of trust anchors before the information in
+the response can be trusted.
+
+The ASN.1 structure of OCSP requests are briefly as follows.  It is
+useful to review the structures to get an understanding of which
+fields are modified by GnuTLS functions.
+
address@hidden
+OCSPRequest     ::=     SEQUENCE @{
+    tbsRequest                  TBSRequest,
+    optionalSignature   [0]     EXPLICIT Signature OPTIONAL @}
+
+TBSRequest      ::=     SEQUENCE @{
+    version             [0]     EXPLICIT Version DEFAULT v1,
+    requestorName       [1]     EXPLICIT GeneralName OPTIONAL,
+    requestList                 SEQUENCE OF Request,
+    requestExtensions   [2]     EXPLICIT Extensions OPTIONAL @}
+
+Request         ::=     SEQUENCE @{
+    reqCert                     CertID,
+    singleRequestExtensions     [0] EXPLICIT Extensions OPTIONAL @}
+
+CertID          ::=     SEQUENCE @{
+    hashAlgorithm       AlgorithmIdentifier,
+    issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
+    issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
+    serialNumber        CertificateSerialNumber @}
address@hidden example
+
+The basic functions to initialize, import, export and deallocate OCSP
+requests are the following.
+
address@hidden,gnutls_ocsp_req_deinit,gnutls_ocsp_req_import,gnutls_ocsp_req_export,gnutls_ocsp_req_print}
+
+There are two interfaces for setting the identity of a certificate in
+a OCSP request, the first being a low-level function when you have the
+issuer name hash, issuer key hash, and certificate serial number in
+binary form.  The second is usually more useful if you have the
+certificate (and its issuer) in a @code{gnutls_x509_crt_t} type.
+There is also a function to extract this information from an OCSP
+request.
+
address@hidden,gnutls_ocsp_req_add_cert,gnutls_ocsp_req_get_cert_id}
+
+Each OCSP request may contain a number of extensions.  Extensions are
+identified by an Object Identifier (OID) and an opaque data buffer
+whose syntax and semantics is implied by the OID.
+
address@hidden,gnutls_ocsp_req_set_extension}
+
+A common OCSP Request extension is the nonce extension (OID
+1.3.6.1.5.5.7.48.1.2), which is used to avoid replay attacks of
+earlier recorded OCSP responses.  The nonce extension carries a value
+that is intended to be sufficiently random and unique so that an
+attacker will not be able to give a stale response for the same nonce.
+
address@hidden,gnutls_ocsp_req_set_nonce,gnutls_ocsp_req_randomize_nonce}
+
+The OCSP response structures is a bit more complex than the request.
+The important ASN.1 structure is as follows.  In practice, all OCSP
+responses contain a Basic OCSP response sub-structure.
+
address@hidden
+OCSPResponse ::= SEQUENCE @{
+   responseStatus         OCSPResponseStatus,
+   responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL @}
+
+OCSPResponseStatus ::= ENUMERATED @{
+    successful            (0),  --Response has valid confirmations
+    malformedRequest      (1),  --Illegal confirmation request
+    internalError         (2),  --Internal error in issuer
+    tryLater              (3),  --Try again later
+                                --(4) is not used
+    sigRequired           (5),  --Must sign the request
+    unauthorized          (6)   --Request unauthorized @}
+
+ResponseBytes ::=       SEQUENCE @{
+    responseType   OBJECT IDENTIFIER,
+    response       OCTET STRING @}
+
+id-pkix-ocsp-basic     OBJECT IDENTIFIER ::= @{ id-pkix-ocsp 1 @}
+
+BasicOCSPResponse       ::= SEQUENCE @{
+   tbsResponseData      ResponseData,
+   signatureAlgorithm   AlgorithmIdentifier,
+   signature            BIT STRING,
+   certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL @}
+
+ResponseData ::= SEQUENCE @{
+   version              [0] EXPLICIT Version DEFAULT v1,
+   responderID              ResponderID,
+   producedAt               GeneralizedTime,
+   responses                SEQUENCE OF SingleResponse,
+   responseExtensions   [1] EXPLICIT Extensions OPTIONAL @}
+
+ResponderID ::= CHOICE @{
+   byName               [1] Name,
+   byKey                [2] KeyHash @}
+
+KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key
+(excluding the tag and length fields)
+
+SingleResponse ::= SEQUENCE @{
+   certID                       CertID,
+   certStatus                   CertStatus,
+   thisUpdate                   GeneralizedTime,
+   nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL,
+   singleExtensions   [1]       EXPLICIT Extensions OPTIONAL @}
+
+CertStatus ::= CHOICE @{
+    good        [0]     IMPLICIT NULL,
+    revoked     [1]     IMPLICIT RevokedInfo,
+    unknown     [2]     IMPLICIT UnknownInfo @}
+
+RevokedInfo ::= SEQUENCE @{
+    revocationTime              GeneralizedTime,
+    revocationReason    [0]     EXPLICIT CRLReason OPTIONAL @}
address@hidden example
+
+We provide basic functions for initialization, importing, exporting
+and deallocating OCSP responses.  The Basic OCSP Response structure is
+automatically parsed when an OCSP Response is imported.
+
address@hidden,gnutls_ocsp_resp_deinit,gnutls_ocsp_resp_import,gnutls_ocsp_resp_export,gnutls_ocsp_resp_print}
+
+The OCSP response needs to be verified against some set of trust
+anchors before it can be relied upon.
+
address@hidden,gnutls_ocsp_resp_verify_direct}
+
 @node Managing encrypted keys
 @section Managing encrypted keys
 @cindex Encrypted keys
@@ -519,6 +692,195 @@ signing_key
 @end 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 smallexample
+
+The input file may also be sent to standard input like this:
+
address@hidden
+$ cat ocsp-request.der | ocsptool --request-info
address@hidden smallexample
+
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 smallexample
+
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 smallexample
+
+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 smallexample
+
+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 smallexample
+
+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 smallexample
+
+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 smallexample
+
+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 smallexample
+
+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 smallexample
+
+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 smallexample
+
+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 smallexample
+
+You may experiment passing different certificates to
address@hidden and @code{--load-signer} to find common error
+conditions for OCSP response verification failures.
+
 @node Smart cards and HSMs
 @section Smart cards and HSMs
 @cindex PKCS #11 tokens
diff --git a/doc/cha-functions.texi b/doc/cha-functions.texi
index 1835fcf..aca17e2 100644
--- a/doc/cha-functions.texi
+++ b/doc/cha-functions.texi
@@ -6,6 +6,7 @@
 * Core TLS API::
 * Datagram TLS API::
 * X509 certificate API::
+* OCSP API::
 * OpenPGP API::
 * PKCS 12 API::
 * PKCS 11 API::
@@ -39,6 +40,15 @@ Their prototypes lie in @file{gnutls/x509.h}.
 
 @include x509-api.texi
 
address@hidden OCSP API
address@hidden @acronym{OCSP} API
address@hidden OCSP Functions
+
+The following functions are for @acronym{OCSP} certificate status
+checking.  Their prototypes lie in @file{gnutls/ocsp.h}.
+
address@hidden ocsp-api.texi
+
 @node OpenPGP API
 @section @acronym{OpenPGP} API
 @cindex OpenPGP API
diff --git a/doc/cha-gtls-examples.texi b/doc/cha-gtls-examples.texi
index 36ec425..c08f9cd 100644
--- a/doc/cha-gtls-examples.texi
+++ b/doc/cha-gtls-examples.texi
@@ -11,6 +11,7 @@ no error checking.
 @menu
 * Client examples::
 * Server examples::
+* OCSP examples::
 * Miscellaneous examples::
 @end menu
 
@@ -209,6 +210,28 @@ used to serve the example client for anonymous 
authentication.
 
 @verbatiminclude examples/ex-serv-anon.c
 
address@hidden OCSP examples
address@hidden OCSP examples
+
address@hidden
+* Generate OCSP request::
+* Verify OCSP response::
address@hidden menu
+
address@hidden Generate OCSP request
address@hidden Generate @acronym{OCSP} request
+
+A small tool to generate OCSP requests.
+
address@hidden examples/ex-ocsp-client.c
+
address@hidden Verify OCSP response
address@hidden Verify @acronym{OCSP} response
+
+A small tool to verify OCSP responses.
+
address@hidden examples/ex-ocsp-verify.c
+
 @node DTLS echo server with X.509 authentication
 @subsection DTLS echo server with @acronym{X.509} authentication
 
diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am
index 8587556..7115e4b 100644
--- a/doc/examples/Makefile.am
+++ b/doc/examples/Makefile.am
@@ -76,6 +76,10 @@ if ENABLE_SRP
 noinst_PROGRAMS += ex-client-srp ex-serv-srp
 endif
 
+if ENABLE_OCSP
+noinst_PROGRAMS += ex-ocsp-client ex-ocsp-verify
+endif
+
 noinst_LTLIBRARIES = libexamples.la
 
 libexamples_la_SOURCES = examples.h ex-alert.c ex-pkcs12.c \
diff --git a/doc/examples/ex-ocsp-client.c b/doc/examples/ex-ocsp-client.c
new file mode 100644
index 0000000..79088de
--- /dev/null
+++ b/doc/examples/ex-ocsp-client.c
@@ -0,0 +1,193 @@
+/* This example code is placed in the public domain. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/ocsp.h>
+
+#include "read-file.h"
+
+/* This program will read a file (argv[1]) containing a certificate in
+   PEM format and print the "CA issuers" and "OCSP address" extensions
+   for the certificate.  If another file is given (argv[2]) it holds
+   the issuer certificate for the first certificate.  Then the tool
+   will generate an OCSP request for the certificate and write it to
+   the file "ocsp-req.der". */
+
+int
+main (int argc, char *argv[])
+{
+  int rc;
+  gnutls_x509_crt_t cert = NULL, issuer = NULL;
+  gnutls_datum_t certdata, issuerdata, tmp;
+  size_t s;
+  unsigned int seq;
+  gnutls_ocsp_req_t ocspreq = NULL;
+  FILE *fh;
+
+  rc = gnutls_global_init ();
+  if (rc < 0)
+    goto done;
+
+  /* Read certificate and print AIA info. */
+
+  rc = gnutls_x509_crt_init (&cert);
+  if (rc < 0)
+    goto done;
+
+  certdata.data = read_binary_file (argv[1], &s);
+  if (certdata.data == NULL)
+    {
+      printf ("cannot read certificate\n");
+      goto done;
+    }
+  certdata.size = s;
+
+  rc = gnutls_x509_crt_import (cert, &certdata, GNUTLS_X509_FMT_PEM);
+  free (certdata.data);
+  if (rc < 0)
+    goto done;
+
+  rc = gnutls_x509_crt_print (cert, GNUTLS_CRT_PRINT_ONELINE, &tmp);
+  if (rc < 0)
+    goto done;
+
+  printf ("cert: %.*s\n", tmp.size, tmp.data);
+
+  gnutls_free (tmp.data); tmp.data = NULL;
+
+  for (seq = 0; ; seq++)
+    {
+      rc = gnutls_x509_crt_get_authority_info_access (cert, seq,
+                                                     GNUTLS_IA_CAISSUERS_URI,
+                                                     &tmp, NULL);
+      if (rc == GNUTLS_E_UNKNOWN_ALGORITHM)
+       continue;
+      if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+       break;
+      if (rc < 0)
+       goto done;
+
+      printf ("CA issuers URI: %.*s\n", tmp.size, tmp.data);
+      gnutls_free (tmp.data);
+      break;
+    }
+
+  if (!tmp.data)
+    printf ("No CA issuers URI found\n");
+
+  for (seq = 0; ; seq++)
+    {
+      rc = gnutls_x509_crt_get_authority_info_access (cert, seq,
+                                                     GNUTLS_IA_OCSP_URI,
+                                                     &tmp, NULL);
+      if (rc == GNUTLS_E_UNKNOWN_ALGORITHM)
+       continue;
+      if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+       break;
+      if (rc < 0)
+       goto done;
+
+      printf ("OCSP URI: %.*s\n", tmp.size, tmp.data);
+      gnutls_free (tmp.data);
+      break;
+    }
+
+  if (!tmp.data)
+    printf ("No OCSP URI URI found\n");
+
+  if (argc < 3)
+    {
+      printf ("Done...\n");
+      goto done;
+    }
+
+  /* Read issuer cert and print brief info about it. */
+
+  rc = gnutls_x509_crt_init (&issuer);
+  if (rc < 0)
+    goto done;
+
+  issuerdata.data = read_binary_file (argv[2], &s);
+  if (issuerdata.data == NULL)
+    {
+      printf ("cannot read issuer\n");
+      goto done;
+    }
+  issuerdata.size = s;
+
+  rc = gnutls_x509_crt_import (issuer, &issuerdata, GNUTLS_X509_FMT_PEM);
+  free (issuerdata.data);
+  if (rc < 0)
+    goto done;
+
+  rc = gnutls_x509_crt_print (issuer, GNUTLS_CRT_PRINT_ONELINE, &tmp);
+  if (rc < 0)
+    goto done;
+
+  printf ("issuer: %.*s\n", tmp.size, tmp.data);
+
+  gnutls_free (tmp.data);
+
+  /* Generate OCSP request and write it. */
+
+  rc = gnutls_ocsp_req_init (&ocspreq);
+  if (rc < 0)
+    goto done;
+
+  rc = gnutls_ocsp_req_add_cert (ocspreq, GNUTLS_DIG_SHA1, issuer, cert);
+  if (rc < 0)
+    goto done;
+
+  rc = gnutls_ocsp_req_print (ocspreq, GNUTLS_OCSP_PRINT_FULL, &tmp);
+  if (rc < 0)
+    goto done;
+
+  printf ("ocsp request: %.*s\n", tmp.size, tmp.data);
+
+  gnutls_free (tmp.data);
+
+  fh = fopen ("ocsp-req.der", "w");
+  if (fh == NULL)
+    goto done;
+
+  rc = gnutls_ocsp_req_export (ocspreq, &tmp);
+  if (rc < 0)
+    goto done;
+
+  s = fwrite (tmp.data, 1, tmp.size, fh);
+
+  gnutls_free (tmp.data);
+
+  if (s != tmp.size)
+    {
+      perror ("fwrite");
+      fclose (fh);
+      goto done;
+    }
+
+  rc = fclose (fh);
+  if (rc != 0)
+    {
+      perror ("fclose");
+      rc = 0;
+      goto done;
+    }
+
+  rc = 0;
+
+ done:
+  if (rc != 0)
+    printf ("error (%d): %s\n", rc, gnutls_strerror (rc));
+  gnutls_ocsp_req_deinit (ocspreq);
+  gnutls_x509_crt_deinit (cert);
+  gnutls_x509_crt_deinit (issuer);
+  gnutls_global_deinit ();
+
+  return rc == 0 ? 0 : 1;
+}
diff --git a/doc/examples/ex-ocsp-verify.c b/doc/examples/ex-ocsp-verify.c
new file mode 100644
index 0000000..37a2122
--- /dev/null
+++ b/doc/examples/ex-ocsp-verify.c
@@ -0,0 +1,153 @@
+/* This example code is placed in the public domain. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/ocsp.h>
+
+#include "read-file.h"
+
+/* This program will read a file (argv[1]) containing an OCSP response
+   and another file (argv[2]) containing a set of OCSP trust anchors.
+   The tool will try to verify the OCSP response against the set of
+   trust anchors.  It will also parse the OCSP response and check that
+   the X.509 certificate is still valid, or print why it is not valid
+   (according to the OCSP response).  */
+
+int
+main (int argc, char *argv[])
+{
+  int rc;
+  gnutls_datum_t tmp;
+  gnutls_ocsp_resp_t ocspresp = NULL;
+  gnutls_x509_trust_list_t trustlist = NULL;
+  gnutls_x509_crt_t *trustcerts = NULL;
+  unsigned int ntrustcerts = 0;
+  unsigned verify, i;
+  size_t s;
+
+  rc = gnutls_global_init ();
+  if (rc < 0)
+    goto done;
+
+  /* Read OCSP response and print it. */
+
+  rc = gnutls_ocsp_resp_init (&ocspresp);
+  if (rc < 0)
+    goto done;
+
+  tmp.data = read_binary_file (argv[1], &s);
+  if (tmp.data == NULL)
+    {
+      printf ("cannot read OCSP response\n");
+      goto done;
+    }
+  tmp.size = s;
+
+  rc = gnutls_ocsp_resp_import (ocspresp, &tmp);
+  free (tmp.data);
+  if (rc < 0)
+    goto done;
+
+  rc = gnutls_ocsp_resp_print (ocspresp, GNUTLS_OCSP_PRINT_FULL, &tmp);
+  if (rc < 0)
+    goto done;
+
+  printf ("ocsp response: %.*s\n", tmp.size, tmp.data);
+
+  gnutls_free (tmp.data);
+
+  if (argc < 3)
+    {
+      printf ("Done...\n");
+      goto done;
+    }
+
+  /* Read X.509 trustlist. */
+
+  rc = gnutls_x509_trust_list_init (&trustlist, 0);
+  if (rc < 0)
+    goto done;
+
+  tmp.data = read_binary_file (argv[2], &s);
+  if (tmp.data == NULL)
+    {
+      printf ("cannot read OCSP response\n");
+      goto done;
+    }
+  tmp.size = s;
+
+  rc = gnutls_x509_crt_list_import2 (&trustcerts, &ntrustcerts, &tmp,
+                                    GNUTLS_X509_FMT_PEM, 0);
+  free (tmp.data);
+  if (rc < 0)
+    goto done;
+
+  for (i = 0; i < ntrustcerts; i++)
+    {
+      gnutls_datum_t out;
+
+      rc = gnutls_x509_crt_print (trustcerts[i],
+                                 GNUTLS_CRT_PRINT_ONELINE, &out);
+      if (rc < 0)
+       goto done;
+
+      printf ("Trust anchor %d: %.*s\n", i, out.size, out.data);
+      gnutls_free (out.data);
+    }
+
+  rc = gnutls_x509_trust_list_add_cas (trustlist, trustcerts, ntrustcerts, 0);
+  gnutls_free (trustcerts);
+  if (rc < 0)
+    goto done;
+
+  printf ("Loaded %d trust anchors\n", ntrustcerts);
+
+  /* Verify it */
+
+  rc = gnutls_ocsp_resp_verify (ocspresp, trustlist, &verify, 0);
+  if (rc < 0)
+    goto done;
+
+  if (verify == 0)
+    printf ("Verification success!\n");
+  else
+    printf ("Verification error!\n");
+
+  if (verify & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND)
+    printf ("Signer cert not found\n");
+
+  if (verify & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR)
+    printf ("Signer cert keyusage error\n");
+
+  if (verify & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER)
+    printf ("Signer cert is not trusted\n");
+
+  if (verify & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM)
+    printf ("Insecure algorithm\n");
+
+  if (verify & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
+    printf ("Signature failure\n");
+
+  if (verify & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED)
+    printf ("Signer cert not yet activated\n");
+
+  if (verify & GNUTLS_OCSP_VERIFY_CERT_EXPIRED)
+    printf ("Signer cert expired\n");
+
+  rc = 0;
+
+ done:
+  if (rc != 0)
+    printf ("error (%d): %s\n", rc, gnutls_strerror (rc));
+  gnutls_x509_trust_list_deinit (trustlist, 1);
+  gnutls_ocsp_resp_deinit (ocspresp);
+  gnutls_global_deinit ();
+
+  return rc == 0 ? 0 : 1;
+}
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
index fc49dab..5057a07 100644
--- a/doc/manpages/Makefile.am
+++ b/doc/manpages/Makefile.am
@@ -359,6 +359,38 @@ APIMANS += gnutls_certificate_set_params_function.3
 APIMANS += gnutls_anon_set_params_function.3
 APIMANS += gnutls_psk_set_params_function.3
 APIMANS += gnutls_hex2bin.3
+APIMANS += gnutls_ocsp_req_init.3
+APIMANS += gnutls_ocsp_req_deinit.3
+APIMANS += gnutls_ocsp_req_import.3
+APIMANS += gnutls_ocsp_req_export.3
+APIMANS += gnutls_ocsp_req_print.3
+APIMANS += gnutls_ocsp_req_get_version.3
+APIMANS += gnutls_ocsp_req_get_cert_id.3
+APIMANS += gnutls_ocsp_req_add_cert_id.3
+APIMANS += gnutls_ocsp_req_add_cert.3
+APIMANS += gnutls_ocsp_req_get_extension.3
+APIMANS += gnutls_ocsp_req_set_extension.3
+APIMANS += gnutls_ocsp_req_get_nonce.3
+APIMANS += gnutls_ocsp_req_set_nonce.3
+APIMANS += gnutls_ocsp_req_randomize_nonce.3
+APIMANS += gnutls_ocsp_resp_init.3
+APIMANS += gnutls_ocsp_resp_deinit.3
+APIMANS += gnutls_ocsp_resp_import.3
+APIMANS += gnutls_ocsp_resp_export.3
+APIMANS += gnutls_ocsp_resp_print.3
+APIMANS += gnutls_ocsp_resp_get_status.3
+APIMANS += gnutls_ocsp_resp_get_response.3
+APIMANS += gnutls_ocsp_resp_get_version.3
+APIMANS += gnutls_ocsp_resp_get_responder.3
+APIMANS += gnutls_ocsp_resp_get_produced.3
+APIMANS += gnutls_ocsp_resp_get_single.3
+APIMANS += gnutls_ocsp_resp_get_extension.3
+APIMANS += gnutls_ocsp_resp_get_nonce.3
+APIMANS += gnutls_ocsp_resp_get_signature_algorithm.3
+APIMANS += gnutls_ocsp_resp_get_signature.3
+APIMANS += gnutls_ocsp_resp_get_certs.3
+APIMANS += gnutls_ocsp_resp_verify_direct.3
+APIMANS += gnutls_ocsp_resp_verify.3
 APIMANS += gnutls_openpgp_crt_init.3
 APIMANS += gnutls_openpgp_crt_deinit.3
 APIMANS += gnutls_openpgp_crt_import.3
@@ -746,6 +778,20 @@ doit:
                echo -n "."; \
        done
        @echo ""
+       @echo -n "Creating man pages for ocsp.h..." && \
+       for i in `$(top_srcdir)/doc/scripts/getfuncs.pl 
<$(top_srcdir)/lib/includes/gnutls/ocsp.h`; do \
+               $(top_srcdir)/doc/scripts/gdoc -man \
+                       -module $(PACKAGE) -sourceversion $(VERSION) \
+                       -bugsto $(PACKAGE_BUGREPORT) \
+                       -pkg-name "$(PACKAGE_NAME)" \
+                       -include "gnutls/ocsp.h" \
+                       -seeinfo $(PACKAGE) -verbatimcopying \
+                       -copyright "2012 Free Software Foundation" \
+                       -function $$i \
+                       $(top_srcdir)/lib/*.c $(top_srcdir)/lib/*/*.c > $$i.3 
2>/dev/null && \
+               echo -n "."; \
+       done
+       @echo ""
        @echo -n "Creating man pages for abstract.h..." && \
        for i in `$(top_srcdir)/doc/scripts/getfuncs.pl 
<$(top_srcdir)/lib/includes/gnutls/abstract.h`; do \
                $(top_srcdir)/doc/scripts/gdoc -man \
diff --git a/doc/reference/gnutls-docs.sgml b/doc/reference/gnutls-docs.sgml
index 63df17c..88f7fbc 100644
--- a/doc/reference/gnutls-docs.sgml
+++ b/doc/reference/gnutls-docs.sgml
@@ -37,6 +37,7 @@
     <xi:include href="xml/crypto.xml"/>
     <xi:include href="xml/pkcs11.xml"/>
     <xi:include href="xml/pkcs12.xml"/>
+    <xi:include href="xml/ocsp.xml"/>
 
   </chapter>
   <index id="api-index-full">
diff --git a/lib/includes/Makefile.am b/lib/includes/Makefile.am
index 5da8bda..31650c1 100644
--- a/lib/includes/Makefile.am
+++ b/lib/includes/Makefile.am
@@ -20,7 +20,7 @@
 
 nobase_include_HEADERS = gnutls/x509.h gnutls/pkcs12.h gnutls/compat.h \
        gnutls/openpgp.h gnutls/crypto.h gnutls/pkcs11.h                \
-       gnutls/abstract.h gnutls/dtls.h
+       gnutls/abstract.h gnutls/dtls.h gnutls/ocsp.h
 
 if ENABLE_CXX
 nobase_include_HEADERS += gnutls/gnutlsxx.h
diff --git a/lib/includes/gnutls/ocsp.h b/lib/includes/gnutls/ocsp.h
new file mode 100644
index 0000000..f748d75
--- /dev/null
+++ b/lib/includes/gnutls/ocsp.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2011-2012 Free Software Foundation, Inc.
+ *
+ * Author: Simon Josefsson
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/* Online Certificate Status Protocol - RFC 2560
+ */
+
+#ifndef GNUTLS_OCSP_H
+#define GNUTLS_OCSP_H
+
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define GNUTLS_OCSP_NONCE "1.3.6.1.5.5.7.48.1.2"
+
+  /**
+   * gnutls_ocsp_print_formats_t:
+   * @GNUTLS_OCSP_PRINT_FULL: Full information about OCSP request/response.
+   *
+   * Enumeration of different OCSP printing variants.
+   */
+  typedef enum gnutls_ocsp_print_formats_t
+    {
+      GNUTLS_OCSP_PRINT_FULL = 0,
+    } gnutls_ocsp_print_formats_t;
+
+  /**
+   * gnutls_ocsp_resp_status_t:
+   * @GNUTLS_OCSP_RESP_SUCCESSFUL: Response has valid confirmations.
+   * @GNUTLS_OCSP_RESP_MALFORMEDREQUEST: Illegal confirmation request
+   * @GNUTLS_OCSP_RESP_INTERNALERROR: Internal error in issuer
+   * @GNUTLS_OCSP_RESP_TRYLATER: Try again later
+   * @GNUTLS_OCSP_RESP_SIGREQUIRED: Must sign the request
+   * @GNUTLS_OCSP_RESP_UNAUTHORIZED: Request unauthorized
+   *
+   * Enumeration of different OCSP response status codes.
+   */
+  typedef enum gnutls_ocsp_resp_status_t
+    {
+      GNUTLS_OCSP_RESP_SUCCESSFUL = 0,
+      GNUTLS_OCSP_RESP_MALFORMEDREQUEST = 1,
+      GNUTLS_OCSP_RESP_INTERNALERROR = 2,
+      GNUTLS_OCSP_RESP_TRYLATER = 3,
+      GNUTLS_OCSP_RESP_SIGREQUIRED = 5,
+      GNUTLS_OCSP_RESP_UNAUTHORIZED = 6
+    } gnutls_ocsp_resp_status_t;
+
+  /**
+   * gnutls_ocsp_cert_status_t:
+   * @GNUTLS_OCSP_CERT_GOOD: Positive response to status inquiry.
+   * @GNUTLS_OCSP_CERT_REVOKED: Certificate has been revoked.
+   * @GNUTLS_OCSP_CERT_UNKNOWN: The responder doesn't know about the
+   *   certificate.
+   *
+   * Enumeration of different OCSP response certificate status codes.
+   */
+  typedef enum gnutls_ocsp_cert_status_t
+    {
+      GNUTLS_OCSP_CERT_GOOD = 0,
+      GNUTLS_OCSP_CERT_REVOKED = 1,
+      GNUTLS_OCSP_CERT_UNKNOWN = 2
+    } gnutls_ocsp_cert_status_t;
+
+  /**
+   * gnutls_x509_crl_reason_t:
+   * @GNUTLS_X509_CRLREASON_UNSPECIFIED: Unspecified reason.
+   * @GNUTLS_X509_CRLREASON_KEYCOMPROMISE: Private key compromised.
+   * @GNUTLS_X509_CRLREASON_CACOMPROMISE: CA compromised.
+   * @GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED: Affiliation has changed.
+   * @GNUTLS_X509_CRLREASON_SUPERSEDED: Certificate superseded.
+   * @GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION: Operation has ceased.
+   * @GNUTLS_X509_CRLREASON_CERTIFICATEHOLD: Certificate is on hold.
+   * @GNUTLS_X509_CRLREASON_REMOVEFROMCRL: Will be removed from delta CRL.
+   * @GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN: Privilege withdrawn.
+   * @GNUTLS_X509_CRLREASON_AACOMPROMISE: AA compromised.
+   *
+   * Enumeration of different reason codes.  Note that this
+   * corresponds to the CRLReason ASN.1 enumeration type, and not the
+   * ReasonFlags ASN.1 bit string.
+   */
+  typedef enum gnutls_x509_crl_reason_t
+    {
+      GNUTLS_X509_CRLREASON_UNSPECIFIED = 0,
+      GNUTLS_X509_CRLREASON_KEYCOMPROMISE = 1,
+      GNUTLS_X509_CRLREASON_CACOMPROMISE = 2,
+      GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED = 3,
+      GNUTLS_X509_CRLREASON_SUPERSEDED = 4,
+      GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION = 5,
+      GNUTLS_X509_CRLREASON_CERTIFICATEHOLD = 6,
+      /* -- value 7 is not used */
+      GNUTLS_X509_CRLREASON_REMOVEFROMCRL = 8,
+      GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN = 9,
+      GNUTLS_X509_CRLREASON_AACOMPROMISE = 10
+    } gnutls_x509_crl_reason_t;
+
+  /**
+   * gnutls_ocsp_verify_reason_t:
+   * @GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND: Signer cert not found.
+   * @GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR: Signer keyusage bits incorrect.
+   * @GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER: Signer is not trusted.
+   * @GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM: Signature using insecure 
algorithm.
+   * @GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE: Signature mismatch.
+   * @GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED: Signer cert is not yet activated.
+   * @GNUTLS_OCSP_VERIFY_CERT_EXPIRED: Signer cert has expired.
+   *
+   * Enumeration of OCSP verify status codes, used by
+   * gnutls_ocsp_resp_verify() and gnutls_ocsp_resp_verify_direct().
+   */
+  typedef enum gnutls_ocsp_verify_reason_t
+    {
+      GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND = 1,
+      GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR = 2,
+      GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER = 4,
+      GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM = 8,
+      GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE = 16,
+      GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED = 32,
+      GNUTLS_OCSP_VERIFY_CERT_EXPIRED = 64
+    } gnutls_ocsp_verify_reason_t;
+
+  struct gnutls_ocsp_req_int;
+  typedef struct gnutls_ocsp_req_int *gnutls_ocsp_req_t;
+
+  int gnutls_ocsp_req_init (gnutls_ocsp_req_t * req);
+  void gnutls_ocsp_req_deinit (gnutls_ocsp_req_t req);
+
+  int gnutls_ocsp_req_import (gnutls_ocsp_req_t req,
+                             const gnutls_datum_t * data);
+  int gnutls_ocsp_req_export (gnutls_ocsp_req_t req, gnutls_datum_t * data);
+  int gnutls_ocsp_req_print (gnutls_ocsp_req_t req,
+                            gnutls_ocsp_print_formats_t format,
+                            gnutls_datum_t * out);
+
+  int gnutls_ocsp_req_get_version (gnutls_ocsp_req_t req);
+
+  int gnutls_ocsp_req_get_cert_id (gnutls_ocsp_req_t req,
+                                  unsigned indx,
+                                  gnutls_digest_algorithm_t *digest,
+                                  gnutls_datum_t *issuer_name_hash,
+                                  gnutls_datum_t *issuer_key_hash,
+                                  gnutls_datum_t *serial_number);
+  int gnutls_ocsp_req_add_cert_id (gnutls_ocsp_req_t req,
+                                  gnutls_digest_algorithm_t digest,
+                                  const gnutls_datum_t *issuer_name_hash,
+                                  const gnutls_datum_t *issuer_key_hash,
+                                  const gnutls_datum_t *serial_number);
+  int gnutls_ocsp_req_add_cert (gnutls_ocsp_req_t req,
+                               gnutls_digest_algorithm_t digest,
+                               gnutls_x509_crt_t issuer,
+                               gnutls_x509_crt_t cert);
+
+  int gnutls_ocsp_req_get_extension (gnutls_ocsp_req_t req,
+                                    unsigned indx,
+                                    gnutls_datum_t *oid,
+                                    unsigned int *critical,
+                                    gnutls_datum_t *data);
+  int gnutls_ocsp_req_set_extension (gnutls_ocsp_req_t req,
+                                    const char *oid,
+                                    unsigned int critical,
+                                    const gnutls_datum_t *data);
+
+  int gnutls_ocsp_req_get_nonce (gnutls_ocsp_req_t req,
+                                unsigned int *critical,
+                                gnutls_datum_t *nonce);
+  int gnutls_ocsp_req_set_nonce (gnutls_ocsp_req_t req,
+                                unsigned int critical,
+                                const gnutls_datum_t *nonce);
+  int gnutls_ocsp_req_randomize_nonce (gnutls_ocsp_req_t req);
+
+  struct gnutls_ocsp_resp_int;
+  typedef struct gnutls_ocsp_resp_int *gnutls_ocsp_resp_t;
+
+  int gnutls_ocsp_resp_init (gnutls_ocsp_resp_t * resp);
+  void gnutls_ocsp_resp_deinit (gnutls_ocsp_resp_t resp);
+
+  int gnutls_ocsp_resp_import (gnutls_ocsp_resp_t resp,
+                              const gnutls_datum_t * data);
+  int gnutls_ocsp_resp_export (gnutls_ocsp_resp_t resp,
+                              gnutls_datum_t * data);
+  int gnutls_ocsp_resp_print (gnutls_ocsp_resp_t resp,
+                             gnutls_ocsp_print_formats_t format,
+                             gnutls_datum_t * out);
+
+  int gnutls_ocsp_resp_get_status (gnutls_ocsp_resp_t resp);
+  int gnutls_ocsp_resp_get_response (gnutls_ocsp_resp_t resp,
+                                    gnutls_datum_t *response_type_oid,
+                                    gnutls_datum_t *response);
+
+  int gnutls_ocsp_resp_get_version (gnutls_ocsp_resp_t resp);
+  int gnutls_ocsp_resp_get_responder (gnutls_ocsp_resp_t resp,
+                                     gnutls_datum_t *dn);
+  time_t gnutls_ocsp_resp_get_produced (gnutls_ocsp_resp_t resp);
+  int gnutls_ocsp_resp_get_single (gnutls_ocsp_resp_t resp,
+                                  unsigned indx,
+                                  gnutls_digest_algorithm_t *digest,
+                                  gnutls_datum_t *issuer_name_hash,
+                                  gnutls_datum_t *issuer_key_hash,
+                                  gnutls_datum_t *serial_number,
+                                  int *cert_status,
+                                  time_t *this_update,
+                                  time_t *next_update,
+                                  time_t *revocation_time,
+                                  int *revocation_reason);
+  int gnutls_ocsp_resp_get_extension (gnutls_ocsp_resp_t resp,
+                                     unsigned indx,
+                                     gnutls_datum_t *oid,
+                                     unsigned int *critical,
+                                     gnutls_datum_t *data);
+  int gnutls_ocsp_resp_get_nonce (gnutls_ocsp_resp_t resp,
+                                 unsigned int *critical,
+                                 gnutls_datum_t *nonce);
+  int gnutls_ocsp_resp_get_signature_algorithm (gnutls_ocsp_resp_t resp);
+  int gnutls_ocsp_resp_get_signature (gnutls_ocsp_resp_t resp,
+                                     gnutls_datum_t *sig);
+  int gnutls_ocsp_resp_get_certs (gnutls_ocsp_resp_t resp,
+                                 gnutls_x509_crt_t ** certs,
+                                 size_t *ncerts);
+
+  int gnutls_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp,
+                                     gnutls_x509_crt_t signercert,
+                                     unsigned *verify,
+                                     int flags);
+  int gnutls_ocsp_resp_verify (gnutls_ocsp_resp_t resp,
+                              gnutls_x509_trust_list_t trustlist,
+                              unsigned *verify,
+                              int flags);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GNUTLS_OCSP_H */
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index fe9d258..0c68c71 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -718,6 +718,38 @@ GNUTLS_3_0_0 {
        gnutls_pubkey_import_ecc_raw2;
        gnutls_record_get_discarded;
        gnutls_x509_crt_get_authority_info_access;
+       gnutls_ocsp_req_add_cert;
+       gnutls_ocsp_req_add_cert_id;
+       gnutls_ocsp_req_deinit;
+       gnutls_ocsp_req_export;
+       gnutls_ocsp_req_get_cert_id;
+       gnutls_ocsp_req_get_extension;
+       gnutls_ocsp_req_get_nonce;
+       gnutls_ocsp_req_get_version;
+       gnutls_ocsp_req_import;
+       gnutls_ocsp_req_init;
+       gnutls_ocsp_req_print;
+       gnutls_ocsp_req_randomize_nonce;
+       gnutls_ocsp_req_set_extension;
+       gnutls_ocsp_req_set_nonce;
+       gnutls_ocsp_resp_deinit;
+       gnutls_ocsp_resp_export;
+       gnutls_ocsp_resp_get_certs;
+       gnutls_ocsp_resp_get_extension;
+       gnutls_ocsp_resp_get_nonce;
+       gnutls_ocsp_resp_get_produced;
+       gnutls_ocsp_resp_get_responder;
+       gnutls_ocsp_resp_get_response;
+       gnutls_ocsp_resp_get_signature;
+       gnutls_ocsp_resp_get_signature_algorithm;
+       gnutls_ocsp_resp_get_single;
+       gnutls_ocsp_resp_get_status;
+       gnutls_ocsp_resp_get_version;
+       gnutls_ocsp_resp_import;
+       gnutls_ocsp_resp_init;
+       gnutls_ocsp_resp_print;
+       gnutls_ocsp_resp_verify;
+       gnutls_ocsp_resp_verify_direct;
        gnutls_privkey_import_ext;
        gnutls_certificate_set_key;
        gnutls_srp_3072_group_generator;
diff --git a/lib/pkix.asn b/lib/pkix.asn
index ef1937c..e0121c6 100644
--- a/lib/pkix.asn
+++ b/lib/pkix.asn
@@ -572,4 +572,113 @@ ProxyPolicy ::= SEQUENCE {
   policyLanguage   OBJECT IDENTIFIER,
   policy           OCTET STRING OPTIONAL }
 
+-- rfc2560
+
+OCSPRequest     ::=     SEQUENCE {
+    tbsRequest                  TBSRequest,
+    optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
+
+TBSRequest      ::=     SEQUENCE {
+    version             [0] EXPLICIT Version DEFAULT v1,
+    requestorName       [1] EXPLICIT GeneralName OPTIONAL,
+    requestList             SEQUENCE OF Request,
+    requestExtensions   [2] EXPLICIT Extensions OPTIONAL }
+
+Signature       ::=     SEQUENCE {
+    signatureAlgorithm   AlgorithmIdentifier,
+    signature            BIT STRING,
+    certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+
+-- comment out, already used above, fortunately with same values and names
+-- Version  ::=  INTEGER  {  v1(0) }
+
+Request ::=     SEQUENCE {
+    reqCert                    CertID,
+    singleRequestExtensions    [0] EXPLICIT Extensions OPTIONAL }
+
+CertID ::= SEQUENCE {
+    hashAlgorithm            AlgorithmIdentifier,
+    issuerNameHash     OCTET STRING, -- Hash of Issuer's DN
+    issuerKeyHash      OCTET STRING, -- Hash of Issuers public key
+    serialNumber       CertificateSerialNumber }
+
+OCSPResponse ::= SEQUENCE {
+   responseStatus         OCSPResponseStatus,
+   responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
+
+OCSPResponseStatus ::= ENUMERATED {
+    successful            (0),      --Response has valid confirmations
+    malformedRequest      (1),      --Illegal confirmation request
+    internalError         (2),      --Internal error in issuer
+    tryLater              (3),      --Try again later
+                                    --(4) is not used
+    sigRequired           (5),      --Must sign the request
+    unauthorized          (6)       --Request unauthorized
+}
+
+ResponseBytes ::=       SEQUENCE {
+    responseType   OBJECT IDENTIFIER,
+    response       OCTET STRING }
+
+BasicOCSPResponse       ::= SEQUENCE {
+   tbsResponseData      ResponseData,
+   signatureAlgorithm   AlgorithmIdentifier,
+   signature            BIT STRING,
+   certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+
+ResponseData ::= SEQUENCE {
+   version              [0] EXPLICIT Version DEFAULT v1,
+   responderID              ResponderID,
+   producedAt               GeneralizedTime,
+   responses                SEQUENCE OF SingleResponse,
+   responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
+
+ResponderID ::= CHOICE {
+-- Changed to work with the libtasn1 parser.
+   byName   [1] EXPLICIT RDNSequence, --Name,
+   byKey    [2] KeyHash }
+
+KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
+                         --(excluding the tag and length fields)
+
+SingleResponse ::= SEQUENCE {
+   certID                       CertID,
+   certStatus                   CertStatus,
+   thisUpdate                   GeneralizedTime,
+   nextUpdate           [0]     EXPLICIT GeneralizedTime OPTIONAL,
+   singleExtensions     [1]     EXPLICIT Extensions OPTIONAL }
+
+CertStatus ::= CHOICE {
+    good                [0]     IMPLICIT NULL,
+    revoked             [1]     IMPLICIT RevokedInfo,
+    unknown             [2]     IMPLICIT UnknownInfo }
+
+RevokedInfo ::= SEQUENCE {
+    revocationTime              GeneralizedTime,
+    revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
+
+UnknownInfo ::= NULL -- this can be replaced with an enumeration
+
+ArchiveCutoff ::= GeneralizedTime
+
+AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER
+
+ServiceLocator ::= SEQUENCE {
+    issuer    Name,
+    locator   AuthorityInfoAccessSyntax }
+
+-- rfc5280
+
+CRLReason ::= ENUMERATED {
+     unspecified             (0),
+     keyCompromise           (1),
+     cACompromise            (2),
+     affiliationChanged      (3),
+     superseded              (4),
+     cessationOfOperation    (5),
+     certificateHold         (6),
+     removeFromCRL           (8),
+     privilegeWithdrawn      (9),
+     aACompromise           (10) }
+
 END
diff --git a/lib/pkix_asn1_tab.c b/lib/pkix_asn1_tab.c
index c42b155..159bba5 100644
--- a/lib/pkix_asn1_tab.c
+++ b/lib/pkix_asn1_tab.c
@@ -407,8 +407,111 @@ const ASN1_ARRAY_TYPE pkix_asn1_tab[] = {
   { "pCPathLenConstraint", 1611153411, NULL },
   { "0", 10, "MAX"},
   { "proxyPolicy", 2, "ProxyPolicy"},
-  { "ProxyPolicy", 536870917, NULL },
+  { "ProxyPolicy", 1610612741, NULL },
   { "policyLanguage", 1073741836, NULL },
   { "policy", 16391, NULL },
+  { "OCSPRequest", 1610612741, NULL },
+  { "tbsRequest", 1073741826, "TBSRequest"},
+  { "optionalSignature", 536895490, "Signature"},
+  { NULL, 2056, "0"},
+  { "TBSRequest", 1610612741, NULL },
+  { "version", 1610653698, "Version"},
+  { NULL, 1073741833, "v1"},
+  { NULL, 2056, "0"},
+  { "requestorName", 1610637314, "GeneralName"},
+  { NULL, 2056, "1"},
+  { "requestList", 1610612747, NULL },
+  { NULL, 2, "Request"},
+  { "requestExtensions", 536895490, "Extensions"},
+  { NULL, 2056, "2"},
+  { "Signature", 1610612741, NULL },
+  { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+  { "signature", 1073741830, NULL },
+  { "certs", 536895499, NULL },
+  { NULL, 1073743880, "0"},
+  { NULL, 2, "Certificate"},
+  { "Request", 1610612741, NULL },
+  { "reqCert", 1073741826, "CertID"},
+  { "singleRequestExtensions", 536895490, "Extensions"},
+  { NULL, 2056, "0"},
+  { "CertID", 1610612741, NULL },
+  { "hashAlgorithm", 1073741826, "AlgorithmIdentifier"},
+  { "issuerNameHash", 1073741831, NULL },
+  { "issuerKeyHash", 1073741831, NULL },
+  { "serialNumber", 2, "CertificateSerialNumber"},
+  { "OCSPResponse", 1610612741, NULL },
+  { "responseStatus", 1073741826, "OCSPResponseStatus"},
+  { "responseBytes", 536895490, "ResponseBytes"},
+  { NULL, 2056, "0"},
+  { "OCSPResponseStatus", 1610874901, NULL },
+  { "successful", 1073741825, "0"},
+  { "malformedRequest", 1073741825, "1"},
+  { "internalError", 1073741825, "2"},
+  { "tryLater", 1073741825, "3"},
+  { "sigRequired", 1073741825, "5"},
+  { "unauthorized", 1, "6"},
+  { "ResponseBytes", 1610612741, NULL },
+  { "responseType", 1073741836, NULL },
+  { "response", 7, NULL },
+  { "BasicOCSPResponse", 1610612741, NULL },
+  { "tbsResponseData", 1073741826, "ResponseData"},
+  { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+  { "signature", 1073741830, NULL },
+  { "certs", 536895499, NULL },
+  { NULL, 1073743880, "0"},
+  { NULL, 2, "Certificate"},
+  { "ResponseData", 1610612741, NULL },
+  { "version", 1610653698, "Version"},
+  { NULL, 1073741833, "v1"},
+  { NULL, 2056, "0"},
+  { "responderID", 1073741826, "ResponderID"},
+  { "producedAt", 1082130449, NULL },
+  { "responses", 1610612747, NULL },
+  { NULL, 2, "SingleResponse"},
+  { "responseExtensions", 536895490, "Extensions"},
+  { NULL, 2056, "1"},
+  { "ResponderID", 1610612754, NULL },
+  { "byName", 1610620930, "RDNSequence"},
+  { NULL, 2056, "1"},
+  { "byKey", 536879106, "KeyHash"},
+  { NULL, 4104, "2"},
+  { "KeyHash", 1073741831, NULL },
+  { "SingleResponse", 1610612741, NULL },
+  { "certID", 1073741826, "CertID"},
+  { "certStatus", 1073741826, "CertStatus"},
+  { "thisUpdate", 1082130449, NULL },
+  { "nextUpdate", 1619025937, NULL },
+  { NULL, 2056, "0"},
+  { "singleExtensions", 536895490, "Extensions"},
+  { NULL, 2056, "1"},
+  { "CertStatus", 1610612754, NULL },
+  { "good", 1610620948, NULL },
+  { NULL, 4104, "0"},
+  { "revoked", 1610620930, "RevokedInfo"},
+  { NULL, 4104, "1"},
+  { "unknown", 536879106, "UnknownInfo"},
+  { NULL, 4104, "2"},
+  { "RevokedInfo", 1610612741, NULL },
+  { "revocationTime", 1082130449, NULL },
+  { "revocationReason", 536895490, "CRLReason"},
+  { NULL, 2056, "0"},
+  { "UnknownInfo", 1073741844, NULL },
+  { "ArchiveCutoff", 1082130449, NULL },
+  { "AcceptableResponses", 1610612747, NULL },
+  { NULL, 12, NULL },
+  { "ServiceLocator", 1610612741, NULL },
+  { "issuer", 1073741826, "Name"},
+  { "locator", 2, "AuthorityInfoAccessSyntax"},
+  { "CRLReason", 537133077, NULL },
+  { "unspecified", 1073741825, "0"},
+  { "keyCompromise", 1073741825, "1"},
+  { "cACompromise", 1073741825, "2"},
+  { "affiliationChanged", 1073741825, "3"},
+  { "superseded", 1073741825, "4"},
+  { "cessationOfOperation", 1073741825, "5"},
+  { "certificateHold", 1073741825, "6"},
+  { "removeFromCRL", 1073741825, "8"},
+  { "privilegeWithdrawn", 1073741825, "9"},
+  { "aACompromise", 1, "10"},
   { NULL, 0, NULL }
 };
diff --git a/lib/x509/Makefile.am b/lib/x509/Makefile.am
index 9386a4e..d16dfc7 100644
--- a/lib/x509/Makefile.am
+++ b/lib/x509/Makefile.am
@@ -57,3 +57,7 @@ libgnutls_x509_la_SOURCES =   \
        x509_write.c            \
        verify-high.c           \
        verify-high.h
+
+if ENABLE_OCSP
+libgnutls_x509_la_SOURCES += ocsp.c ocsp_output.c
+endif
diff --git a/lib/x509/ocsp.c b/lib/x509/ocsp.c
new file mode 100644
index 0000000..ae23168
--- /dev/null
+++ b/lib/x509/ocsp.c
@@ -0,0 +1,2160 @@
+/*
+ * Copyright (C) 2011-2012 Free Software Foundation, Inc.
+ * Author: Simon Josefsson
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/* Online Certificate Status Protocol - RFC 2560
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_global.h>
+#include <gnutls_errors.h>
+#include <libtasn1.h>
+#include <gnutls_pk.h>
+#include "common.h"
+#include "hash.h"
+#include "verify-high.h"
+
+#include <gnutls/ocsp.h>
+
+typedef struct gnutls_ocsp_req_int
+{
+  ASN1_TYPE req;
+} gnutls_ocsp_req_int;
+
+typedef struct gnutls_ocsp_resp_int
+{
+  ASN1_TYPE resp;
+  gnutls_datum_t response_type_oid;
+  ASN1_TYPE basicresp;
+} gnutls_ocsp_resp_int;
+
+#define MAX_TIME 64
+
+/**
+ * gnutls_ocsp_req_init:
+ * @req: The structure to be initialized
+ *
+ * This function will initialize an OCSP request structure.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_ocsp_req_init (gnutls_ocsp_req_t * req)
+{
+  gnutls_ocsp_req_t tmp = gnutls_calloc (1, sizeof (gnutls_ocsp_req_int));
+  int ret;
+
+  if (!tmp)
+    return GNUTLS_E_MEMORY_ERROR;
+
+  ret = asn1_create_element (_gnutls_get_pkix (), "PKIX1.OCSPRequest",
+                            &tmp->req);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      gnutls_free (tmp);
+      return _gnutls_asn2err (ret);
+    }
+
+  *req = tmp;
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_req_deinit:
+ * @req: The structure to be deinitialized
+ *
+ * This function will deinitialize a OCSP request structure.
+ **/
+void
+gnutls_ocsp_req_deinit (gnutls_ocsp_req_t req)
+{
+  if (!req)
+    return;
+
+  if (req->req)
+    asn1_delete_structure (&req->req);
+
+  req->req = NULL;
+
+  gnutls_free (req);
+}
+
+/**
+ * gnutls_ocsp_resp_init:
+ * @resp: The structure to be initialized
+ *
+ * This function will initialize an OCSP response structure.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_ocsp_resp_init (gnutls_ocsp_resp_t * resp)
+{
+  gnutls_ocsp_resp_t tmp = gnutls_calloc (1, sizeof (gnutls_ocsp_resp_int));
+  int ret;
+
+  if (!tmp)
+    return GNUTLS_E_MEMORY_ERROR;
+
+  ret = asn1_create_element (_gnutls_get_pkix (),
+                               "PKIX1.OCSPResponse", &tmp->resp);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      gnutls_free (tmp);
+      return _gnutls_asn2err (ret);
+    }
+
+  ret = asn1_create_element (_gnutls_get_pkix (),
+                            "PKIX1.BasicOCSPResponse", &tmp->basicresp);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&tmp->resp);
+      gnutls_free (tmp);
+      return _gnutls_asn2err (ret);
+    }
+
+  *resp = tmp;
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_resp_deinit:
+ * @resp: The structure to be deinitialized
+ *
+ * This function will deinitialize a OCSP response structure.
+ **/
+void
+gnutls_ocsp_resp_deinit (gnutls_ocsp_resp_t resp)
+{
+  if (!resp)
+    return;
+
+  if (resp->resp)
+    asn1_delete_structure (&resp->resp);
+  gnutls_free (resp->response_type_oid.data);
+  if (resp->basicresp)
+    asn1_delete_structure (&resp->basicresp);
+
+  resp->resp = NULL;
+  resp->response_type_oid.data = NULL;
+  resp->basicresp = NULL;
+
+  gnutls_free (resp);
+}
+
+/**
+ * gnutls_ocsp_req_import:
+ * @req: The structure to store the parsed request.
+ * @data: DER encoded OCSP request.
+ *
+ * This function will convert the given DER encoded OCSP request to
+ * the native #gnutls_ocsp_req_t format. The output will be stored in
+ * @req.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_ocsp_req_import (gnutls_ocsp_req_t req,
+                        const gnutls_datum_t * data)
+{
+  int ret = 0;
+
+  if (req == NULL || data == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  if (req->req)
+    {
+      /* Any earlier asn1_der_decoding will modify the ASN.1
+         structure, so we need to replace it with a fresh
+         structure. */
+      asn1_delete_structure (&req->req);
+
+      ret = asn1_create_element (_gnutls_get_pkix (),
+                                    "PKIX1.OCSPRequest", &req->req);
+      if (ret != ASN1_SUCCESS)
+        {
+          gnutls_assert ();
+          return _gnutls_asn2err (ret);
+        }
+    }
+
+  ret = asn1_der_decoding (&req->req, data->data, data->size, NULL);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (ret);
+    }
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_resp_import:
+ * @resp: The structure to store the parsed response.
+ * @data: DER encoded OCSP response.
+ *
+ * This function will convert the given DER encoded OCSP response to
+ * the native #gnutls_ocsp_resp_t format.  It also decodes the Basic
+ * OCSP Response part, if any.  The output will be stored in @resp.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_ocsp_resp_import (gnutls_ocsp_resp_t resp,
+                        const gnutls_datum_t * data)
+{
+  int ret = 0;
+
+  if (resp == NULL || data == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  if (resp->resp)
+    {
+      /* Any earlier asn1_der_decoding will modify the ASN.1
+         structure, so we need to replace it with a fresh
+         structure. */
+      asn1_delete_structure (&resp->resp);
+
+      ret = asn1_create_element (_gnutls_get_pkix (),
+                                "PKIX1.OCSPResponse", &resp->resp);
+      if (ret != ASN1_SUCCESS)
+        {
+          gnutls_assert ();
+          return _gnutls_asn2err (ret);
+        }
+    }
+
+  ret = asn1_der_decoding (&resp->resp, data->data, data->size, NULL);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (ret);
+    }
+
+  if (gnutls_ocsp_resp_get_status (resp) != GNUTLS_OCSP_RESP_SUCCESSFUL)
+    return GNUTLS_E_SUCCESS;
+
+  ret = _gnutls_x509_read_value (resp->resp, "responseBytes.responseType",
+                                &resp->response_type_oid, 0);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+#define OCSP_BASIC "1.3.6.1.5.5.7.48.1.1"
+
+  if (resp->response_type_oid.size == sizeof (OCSP_BASIC)
+      && memcmp (resp->response_type_oid.data, OCSP_BASIC,
+                resp->response_type_oid.size) == 0)
+    {
+      gnutls_datum_t d;
+
+      if (resp->basicresp)
+       {
+         asn1_delete_structure (&resp->basicresp);
+
+         ret = asn1_create_element (_gnutls_get_pkix (),
+                                    "PKIX1.BasicOCSPResponse", 
&resp->basicresp);
+         if (ret != ASN1_SUCCESS)
+           {
+             gnutls_assert ();
+             return _gnutls_asn2err (ret);
+           }
+       }
+
+      ret = _gnutls_x509_read_value (resp->resp, "responseBytes.response",
+                                    &d, 0);
+      if (ret < 0)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+
+      ret = asn1_der_decoding (&resp->basicresp, d.data, d.size, NULL);
+      gnutls_free (d.data);
+      if (ret != ASN1_SUCCESS)
+       {
+         gnutls_assert ();
+         return _gnutls_asn2err (ret);
+       }
+    }
+  else
+    resp->basicresp = NULL;
+
+  return GNUTLS_E_SUCCESS;
+}
+
+static int
+export (ASN1_TYPE node, const char *name, gnutls_datum_t * data)
+{
+  int ret;
+  int len = 0;
+
+  ret = asn1_der_coding (node, name, NULL, &len, NULL);
+  if (ret != ASN1_MEM_ERROR)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (ret);
+    }
+  data->size = len;
+  data->data = gnutls_malloc (len);
+  if (data->data == NULL)
+    return GNUTLS_E_MEMORY_ERROR;
+  ret = asn1_der_coding (node, name, data->data, &len, NULL);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (ret);
+    }
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_req_export:
+ * @req: Holds the OCSP request
+ * @data: newly allocate buffer holding DER encoded OCSP request
+ *
+ * This function will export the OCSP request to DER format.
+ *
+ * Returns: In case of failure a negative error code will be
+ *   returned, and 0 on success.
+ **/
+int
+gnutls_ocsp_req_export (gnutls_ocsp_req_t req, gnutls_datum_t * data)
+{
+  int ret;
+
+  if (req == NULL || data == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  /* XXX remove when we support these fields */
+  asn1_write_value (req->req, "tbsRequest.requestorName", NULL, 0);
+  asn1_write_value (req->req, "optionalSignature", NULL, 0);
+
+  /* prune extension field if we don't have any extension */
+  ret = gnutls_ocsp_req_get_extension (req, 0, NULL, NULL, NULL);
+  if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+    asn1_write_value (req->req, "tbsRequest.requestExtensions", NULL, 0);
+
+  return export (req->req, "", data);
+}
+
+/**
+ * gnutls_ocsp_resp_export:
+ * @resp: Holds the OCSP response
+ * @data: newly allocate buffer holding DER encoded OCSP response
+ *
+ * This function will export the OCSP response to DER format.
+ *
+ * Returns: In case of failure a negative error code will be
+ *   returned, and 0 on success.
+ **/
+int
+gnutls_ocsp_resp_export (gnutls_ocsp_resp_t resp, gnutls_datum_t * data)
+{
+  if (resp == NULL || data == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  return export (resp->resp, "", data);
+}
+
+/**
+ * gnutls_ocsp_req_get_version:
+ * @req: should contain a #gnutls_ocsp_req_t structure
+ *
+ * This function will return the version of the OCSP request.
+ * Typically this is always 1 indicating version 1.
+ *
+ * Returns: version of OCSP request, or a negative error code on error.
+ **/
+int
+gnutls_ocsp_req_get_version (gnutls_ocsp_req_t req)
+{
+  opaque version[8];
+  int len, ret;
+
+  if (req == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  len = sizeof (version);
+  ret = asn1_read_value (req->req, "tbsRequest.version", version, &len);
+  if (ret != ASN1_SUCCESS)
+    {
+      if (ret == ASN1_ELEMENT_NOT_FOUND)
+        return 1;               /* the DEFAULT version */
+      gnutls_assert ();
+      return _gnutls_asn2err (ret);
+    }
+
+  return (int) version[0] + 1;
+}
+
+/**
+ * gnutls_ocsp_req_get_cert_id:
+ * @req: should contain a #gnutls_ocsp_req_t structure
+ * @indx: Specifies which extension OID to get. Use (0) to get the first one.
+ * @digest: output variable with #gnutls_digest_algorithm_t hash algorithm
+ * @issuer_name_hash: output buffer with hash of issuer's DN
+ * @issuer_key_hash: output buffer with hash of issuer's public key
+ * @serial_number: output buffer with serial number of certificate to check
+ *
+ * This function will return the certificate information of the
+ * @indx'ed request in the OCSP request.  The information returned
+ * corresponds to the CertID structure:
+ *
+ * <informalexample><programlisting>
+ *    CertID          ::=     SEQUENCE {
+ *        hashAlgorithm       AlgorithmIdentifier,
+ *        issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
+ *        issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
+ *        serialNumber        CertificateSerialNumber }
+ * </programlisting></informalexample>
+ *
+ * Each of the pointers to output variables may be NULL to indicate
+ * that the caller is not interested in that value.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error code is returned.  If you have reached the last
+ *   CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
+ *   returned.
+ **/
+int
+gnutls_ocsp_req_get_cert_id (gnutls_ocsp_req_t req,
+                            unsigned indx,
+                            gnutls_digest_algorithm_t *digest,
+                            gnutls_datum_t *issuer_name_hash,
+                            gnutls_datum_t *issuer_key_hash,
+                            gnutls_datum_t *serial_number)
+{
+  gnutls_datum_t sa;
+  char name[ASN1_MAX_NAME_SIZE];
+  int ret;
+
+  if (req == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  snprintf (name, sizeof (name),
+           "tbsRequest.requestList.?%u.reqCert.hashAlgorithm.algorithm",
+           indx + 1);
+  ret = _gnutls_x509_read_value (req->req, name, &sa, 0);
+  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
+    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+  else if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = _gnutls_x509_oid2digest_algorithm (sa.data);
+  _gnutls_free_datum (&sa);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  if (digest)
+    *digest = ret;
+
+  if (issuer_name_hash)
+    {
+      snprintf (name, sizeof (name),
+               "tbsRequest.requestList.?%u.reqCert.issuerNameHash", indx + 1);
+      ret = _gnutls_x509_read_value (req->req, name, issuer_name_hash, 0);
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+    }
+
+  if (issuer_key_hash)
+    {
+      snprintf (name, sizeof (name),
+               "tbsRequest.requestList.?%u.reqCert.issuerKeyHash", indx + 1);
+      ret = _gnutls_x509_read_value (req->req, name, issuer_key_hash, 0);
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         if (issuer_name_hash)
+           gnutls_free (issuer_name_hash->data);
+         return ret;
+       }
+    }
+
+  if (serial_number)
+    {
+      snprintf (name, sizeof (name),
+               "tbsRequest.requestList.?%u.reqCert.serialNumber", indx + 1);
+      ret = _gnutls_x509_read_value (req->req, name, serial_number, 0);
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         if (issuer_name_hash)
+           gnutls_free (issuer_name_hash->data);
+         if (issuer_key_hash)
+           gnutls_free (issuer_key_hash->data);
+         return ret;
+       }
+    }
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_req_add_cert_id:
+ * @req: should contain a #gnutls_ocsp_req_t structure
+ * @digest: hash algorithm, a #gnutls_digest_algorithm_t value
+ * @issuer_name_hash: hash of issuer's DN
+ * @issuer_key_hash: hash of issuer's public key
+ * @serial_number: serial number of certificate to check
+ *
+ * This function will add another request to the OCSP request for a
+ * particular certificate having the issuer name hash of
+ * @issuer_name_hash and issuer key hash of @issuer_key_hash (both
+ * hashed using @digest) and serial number @serial_number.
+ *
+ * The information needed corresponds to the CertID structure:
+ *
+ * <informalexample><programlisting>
+ *    CertID          ::=     SEQUENCE {
+ *        hashAlgorithm       AlgorithmIdentifier,
+ *        issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
+ *        issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
+ *        serialNumber        CertificateSerialNumber }
+ * </programlisting></informalexample>
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error code is returned.
+ **/
+int
+gnutls_ocsp_req_add_cert_id (gnutls_ocsp_req_t req,
+                            gnutls_digest_algorithm_t digest,
+                            const gnutls_datum_t *issuer_name_hash,
+                            const gnutls_datum_t *issuer_key_hash,
+                            const gnutls_datum_t *serial_number)
+{
+  int result;
+  const char *oid;
+
+  if (req == NULL || issuer_name_hash == NULL
+      || issuer_key_hash == NULL || serial_number == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  oid = _gnutls_x509_digest_to_oid (digest);
+  if (oid == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  result = asn1_write_value (req->req, "tbsRequest.requestList", "NEW", 1);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_write_value
+    (req->req, "tbsRequest.requestList.?LAST.reqCert.hashAlgorithm.algorithm",
+     oid, 1);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  /* XXX we don't support any algorithm with parameters */
+  result = asn1_write_value
+    (req->req, "tbsRequest.requestList.?LAST.reqCert.hashAlgorithm.parameters",
+     ASN1_NULL, ASN1_NULL_SIZE);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_write_value
+    (req->req, "tbsRequest.requestList.?LAST.reqCert.issuerNameHash",
+     issuer_name_hash->data, issuer_name_hash->size);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_write_value
+    (req->req, "tbsRequest.requestList.?LAST.reqCert.issuerKeyHash",
+     issuer_key_hash->data, issuer_key_hash->size);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_write_value
+    (req->req, "tbsRequest.requestList.?LAST.reqCert.serialNumber",
+     serial_number->data, serial_number->size);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  /* XXX add separate function that can add extensions too */
+  result = asn1_write_value
+    (req->req, "tbsRequest.requestList.?LAST.singleRequestExtensions",
+     NULL, 0);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_req_add_cert:
+ * @req: should contain a #gnutls_ocsp_req_t structure
+ * @digest: hash algorithm, a #gnutls_digest_algorithm_t value
+ * @issuer: issuer of @subject certificate
+ * @cert: certificate to request status for
+ *
+ * This function will add another request to the OCSP request for a
+ * particular certificate.  The issuer name hash, issuer key hash, and
+ * serial number fields is populated as follows.  The issuer name and
+ * the serial number is taken from @cert.  The issuer key is taken
+ * from @issuer.  The hashed values will be hashed using the @digest
+ * algorithm, normally %GNUTLS_DIG_SHA1.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error code is returned.
+ **/
+int
+gnutls_ocsp_req_add_cert (gnutls_ocsp_req_t req,
+                         gnutls_digest_algorithm_t digest,
+                         gnutls_x509_crt_t issuer,
+                         gnutls_x509_crt_t cert)
+{
+  int ret;
+  gnutls_datum_t sn, tmp, inh, ikh;
+  char inh_buf[MAX_HASH_SIZE];
+  char ikh_buf[MAX_HASH_SIZE];
+  size_t inhlen = MAX_HASH_SIZE;
+  size_t ikhlen = MAX_HASH_SIZE;
+
+  if (req == NULL || issuer == NULL || cert == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  ret = _gnutls_x509_der_encode (cert->cert,
+                                "tbsCertificate.issuer.rdnSequence",
+                                &tmp, 0);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = gnutls_fingerprint (digest, &tmp, inh_buf, &inhlen);
+  gnutls_free (tmp.data);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+  inh.size = inhlen;
+  inh.data = inh_buf;
+
+  ret = _gnutls_x509_read_value
+    (issuer->cert, "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
+     &tmp, 2);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = gnutls_fingerprint (digest, &tmp, ikh_buf, &ikhlen);
+  gnutls_free (tmp.data);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+  ikh.size = ikhlen;
+  ikh.data = ikh_buf;
+
+  ret = _gnutls_x509_read_value (cert->cert, "tbsCertificate.serialNumber",
+                                &sn, 0);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = gnutls_ocsp_req_add_cert_id (req, digest, &inh, &ikh, &sn);
+  gnutls_free (sn.data);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_req_get_extension:
+ * @req: should contain a #gnutls_ocsp_req_t structure
+ * @indx: Specifies which extension OID to get. Use (0) to get the first one.
+ * @oid: will hold newly allocated buffer with OID of extension, may be NULL
+ * @critical: output variable with critical flag, may be NULL.
+ * @data: will hold newly allocated buffer with extension data, may be NULL
+ *
+ * This function will return all information about the requested
+ * extension in the OCSP request.  The information returned is the
+ * OID, the critical flag, and the data itself.  The extension OID
+ * will be stored as a string.  Any of @oid, @critical, and @data may
+ * be NULL which means that the caller is not interested in getting
+ * that information back.
+ *
+ * The caller needs to deallocate memory by calling gnutls_free() on
+ * @oid->data and @data->data.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error code is returned.  If you have reached the last
+ *   extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
+ *   be returned.
+ **/
+int
+gnutls_ocsp_req_get_extension (gnutls_ocsp_req_t req,
+                              unsigned indx,
+                              gnutls_datum_t *oid,
+                              unsigned int *critical,
+                              gnutls_datum_t *data)
+{
+  int ret;
+  char str_critical[10];
+  char name[ASN1_MAX_NAME_SIZE];
+  int len;
+
+  if (!req)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  snprintf (name, sizeof (name), "tbsRequest.requestExtensions.?%u.critical",
+           indx + 1);
+  len = sizeof (str_critical);
+  ret = asn1_read_value (req->req, name, str_critical, &len);
+  if (ret == ASN1_ELEMENT_NOT_FOUND)
+    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+  else if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (ret);
+    }
+
+  if (critical)
+    {
+      if (str_critical[0] == 'T')
+       *critical = 1;
+      else
+       *critical = 0;
+    }
+
+  if (oid)
+    {
+      snprintf (name, sizeof (name),
+               "tbsRequest.requestExtensions.?%u.extnID", indx + 1);
+      ret = _gnutls_x509_read_value (req->req, name, oid, 0);
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+    }
+
+  if (data)
+    {
+      snprintf (name, sizeof (name),
+               "tbsRequest.requestExtensions.?%u.extnValue", indx + 1);
+      ret = _gnutls_x509_read_value (req->req, name, data, 0);
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         if (oid)
+           gnutls_free (oid->data);
+         return ret;
+       }
+    }
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_req_set_extension:
+ * @req: should contain a #gnutls_ocsp_req_t structure
+ * @oid: buffer with OID of extension as a string.
+ * @critical: critical flag, normally false.
+ * @data: the extension data
+ *
+ * This function will add an extension to the OCSP request.  Calling
+ * this function multiple times for the same OID will overwrite values
+ * from earlier calls.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error code is returned.
+ **/
+int
+gnutls_ocsp_req_set_extension (gnutls_ocsp_req_t req,
+                              const char *oid,
+                              unsigned int critical,
+                              const gnutls_datum_t *data)
+{
+  if (req == NULL || oid == NULL || data == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  return set_extension (req->req, "tbsRequest.requestExtensions", oid,
+                       data, critical);
+}
+
+/**
+ * gnutls_ocsp_req_get_nonce:
+ * @req: should contain a #gnutls_ocsp_req_t structure
+ * @critical: whether nonce extension is marked critical, or NULL
+ * @nonce: will hold newly allocated buffer with nonce data
+ *
+ * This function will return the OCSP request nonce extension data.
+ *
+ * The caller needs to deallocate memory by calling gnutls_free() on
+ * @nonce->data.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error code is returned.
+ **/
+int
+gnutls_ocsp_req_get_nonce (gnutls_ocsp_req_t req,
+                          unsigned int *critical,
+                          gnutls_datum_t *nonce)
+{
+  int ret;
+  size_t l = 0;
+  gnutls_datum_t tmp;
+
+  if (req == NULL || nonce == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  ret = get_extension (req->req, "tbsRequest.requestExtensions",
+                      GNUTLS_OCSP_NONCE, 0,
+                      &tmp, critical);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = _gnutls_x509_decode_octet_string (NULL, tmp.data, (size_t) tmp.size,
+                                         NULL, &l);
+  if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
+    {
+      gnutls_assert ();
+      gnutls_free (tmp.data);
+      return ret;
+    }
+
+  nonce->data = gnutls_malloc (l);
+  if (nonce->data == NULL)
+    {
+      gnutls_assert ();
+      gnutls_free (tmp.data);
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  ret = _gnutls_x509_decode_octet_string (NULL, tmp.data, (size_t) tmp.size,
+                                         nonce->data, &l);
+  gnutls_free (tmp.data);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+  nonce->size = l;
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_req_set_nonce:
+ * @req: should contain a #gnutls_ocsp_req_t structure
+ * @critical: critical flag, normally false.
+ * @nonce: the nonce data
+ *
+ * This function will add an nonce extension to the OCSP request.
+ * Calling this function multiple times will overwrite values from
+ * earlier calls.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error code is returned.
+ **/
+int
+gnutls_ocsp_req_set_nonce (gnutls_ocsp_req_t req,
+                          unsigned int critical,
+                          const gnutls_datum_t *nonce)
+{
+  int ret;
+  gnutls_datum_t dernonce;
+  unsigned char temp[SIZEOF_UNSIGNED_LONG_INT + 1];
+  int len;
+
+  if (req == NULL || nonce == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  asn1_length_der (nonce->size, temp, &len);
+
+  dernonce.size = 1 + len + nonce->size;
+  dernonce.data = gnutls_malloc (dernonce.size);
+  if (dernonce.data == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  dernonce.data[0] = '\x04';
+  memcpy (dernonce.data + 1, temp, len);
+  memcpy (dernonce.data + 1 + len, nonce->data, nonce->size);
+
+  ret =  set_extension (req->req, "tbsRequest.requestExtensions",
+                       GNUTLS_OCSP_NONCE, &dernonce, critical);
+  gnutls_free (dernonce.data);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  return ret;
+}
+
+/**
+ * gnutls_ocsp_req_randomize_nonce:
+ * @req: should contain a #gnutls_ocsp_req_t structure
+ *
+ * This function will add or update an nonce extension to the OCSP
+ * request with a newly generated random value.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error code is returned.
+ **/
+int
+gnutls_ocsp_req_randomize_nonce (gnutls_ocsp_req_t req)
+{
+  int ret;
+  char rndbuf[23];
+  gnutls_datum_t nonce = { rndbuf, sizeof (rndbuf) };
+
+  if (req == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  ret = gnutls_rnd (GNUTLS_RND_NONCE, rndbuf, sizeof (rndbuf));
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = gnutls_ocsp_req_set_nonce (req, 0, &nonce);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_resp_get_status:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ *
+ * This function will return the status of a OCSP response, an
+ * #gnutls_ocsp_resp_status_t enumeration.
+ *
+ * Returns: status of OCSP request as a #gnutls_ocsp_resp_status_t, or
+ *   a negative error code on error.
+ **/
+int
+gnutls_ocsp_resp_get_status (gnutls_ocsp_resp_t resp)
+{
+  opaque str[1];
+  int len, ret;
+
+  if (resp == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  len = sizeof (str);
+  ret = asn1_read_value (resp->resp, "responseStatus", str, &len);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (ret);
+    }
+
+  switch (str[0])
+    {
+    case GNUTLS_OCSP_RESP_SUCCESSFUL:
+    case GNUTLS_OCSP_RESP_MALFORMEDREQUEST:
+    case GNUTLS_OCSP_RESP_INTERNALERROR:
+    case GNUTLS_OCSP_RESP_TRYLATER:
+    case GNUTLS_OCSP_RESP_SIGREQUIRED:
+    case GNUTLS_OCSP_RESP_UNAUTHORIZED:
+      break;
+    default:
+      return GNUTLS_E_UNEXPECTED_PACKET;
+    }
+
+  return (int) str[0];
+}
+
+/**
+ * gnutls_ocsp_resp_get_response:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ * @response_type_oid: newly allocated output buffer with response type OID
+ * @response: newly allocated output buffer with DER encoded response
+ *
+ * This function will extract the response type OID in and the
+ * response data from an OCSP response.  Normally the
+ * @response_type_oid is always "1.3.6.1.5.5.7.48.1.1" which means the
+ * @response should be decoded as a Basic OCSP Response, but
+ * technically other response types could be used.
+ *
+ * This function is typically only useful when you want to extract the
+ * response type OID of an response for diagnostic purposes.
+ * Otherwise gnutls_ocsp_resp_import() will decode the basic OCSP
+ * response part and the caller need not worry about that aspect.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_ocsp_resp_get_response (gnutls_ocsp_resp_t resp,
+                              gnutls_datum_t *response_type_oid,
+                              gnutls_datum_t *response)
+{
+  int ret;
+
+  if (resp == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  if (response_type_oid != NULL)
+    {
+      ret = _gnutls_x509_read_value (resp->resp, "responseBytes.responseType",
+                                    response_type_oid, 0);
+      if (ret < 0)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+    }
+
+  if (response != NULL)
+    {
+      ret = _gnutls_x509_read_value (resp->resp, "responseBytes.response",
+                                    response, 0);
+      if (ret < 0)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+    }
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_resp_get_version:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ *
+ * This function will return the version of the Basic OCSP Response.
+ * Typically this is always 1 indicating version 1.
+ *
+ * Returns: version of Basic OCSP response, or a negative error code
+ *   on error.
+ **/
+int
+gnutls_ocsp_resp_get_version (gnutls_ocsp_resp_t resp)
+{
+  opaque version[8];
+  int len, ret;
+
+  if (resp == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  len = sizeof (version);
+  ret = asn1_read_value (resp->resp, "tbsResponseData.version", version, &len);
+  if (ret != ASN1_SUCCESS)
+    {
+      if (ret == ASN1_ELEMENT_NOT_FOUND)
+        return 1;               /* the DEFAULT version */
+      gnutls_assert ();
+      return _gnutls_asn2err (ret);
+    }
+
+  return (int) version[0] + 1;
+}
+
+/**
+ * gnutls_ocsp_resp_get_responder:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ * @dn: newly allocated buffer with name
+ *
+ * This function will extract the name of the Basic OCSP Response in
+ * the provided buffer. The name will be in the form
+ * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
+ * will be ASCII or UTF-8 encoded, depending on the certificate data.
+ *
+ * The caller needs to deallocate memory by calling gnutls_free() on
+ * @dn->data.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error code is returned.
+ **/
+int
+gnutls_ocsp_resp_get_responder (gnutls_ocsp_resp_t resp,
+                               gnutls_datum_t *dn)
+{
+  int ret;
+  size_t l = 0;
+
+  if (resp == NULL || dn == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  ret =  _gnutls_x509_parse_dn
+    (resp->basicresp, "tbsResponseData.responderID.byName",
+     NULL, &l);
+  if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  dn->data = gnutls_malloc (l);
+  if (dn->data == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  ret =  _gnutls_x509_parse_dn
+    (resp->basicresp, "tbsResponseData.responderID.byName",
+     dn->data, &l);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  dn->size = l;
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_resp_get_produced:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ *
+ * This function will return the time when the OCSP response was
+ * signed.
+ *
+ * Returns: signing time, or (time_t)-1 on error.
+ **/
+time_t
+gnutls_ocsp_resp_get_produced (gnutls_ocsp_resp_t resp)
+{
+  char ttime[MAX_TIME];
+  int len, ret;
+  time_t c_time;
+
+  if (resp == NULL || resp->basicresp == NULL)
+    {
+      gnutls_assert ();
+      return (time_t) (-1);
+    }
+
+  len = sizeof (ttime) - 1;
+  ret = asn1_read_value (resp->basicresp, "tbsResponseData.producedAt",
+                        ttime, &len);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return (time_t) (-1);
+    }
+
+  c_time = _gnutls_x509_generalTime2gtime (ttime);
+
+  return c_time;
+}
+
+/**
+ * gnutls_ocsp_resp_get_single:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ * @indx: Specifies which extension OID to get. Use (0) to get the first one.
+ * @digest: output variable with #gnutls_digest_algorithm_t hash algorithm
+ * @issuer_name_hash: output buffer with hash of issuer's DN
+ * @issuer_key_hash: output buffer with hash of issuer's public key
+ * @serial_number: output buffer with serial number of certificate to check
+ * @cert_status: a certificate status, a #gnutls_ocsp_cert_status_t enum.
+ * @this_update: time at which the status is known to be correct.
+ * @next_update: when newer information will be available, or (time_t)-1 if 
unspecified
+ * @revocation_time: when @cert_status is %GNUTLS_OCSP_CERT_REVOKED, holds 
time of revocation.
+ * @revocation_reason: revocation reason, a #gnutls_x509_crl_reason_t enum.
+ *
+ * This function will return the certificate information of the
+ * @indx'ed response in the Basic OCSP Response @resp.  The
+ * information returned corresponds to the SingleResponse structure
+ * except the final singleExtensions, reproduced here for illustration:
+ *
+ * <informalexample><programlisting>
+ * SingleResponse ::= SEQUENCE {
+ *    certID                       CertID,
+ *    certStatus                   CertStatus,
+ *    thisUpdate                   GeneralizedTime,
+ *    nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL,
+ *    singleExtensions   [1]       EXPLICIT Extensions OPTIONAL }
+ *
+ *    CertID          ::=     SEQUENCE {
+ *        hashAlgorithm       AlgorithmIdentifier,
+ *        issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
+ *        issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
+ *        serialNumber        CertificateSerialNumber }
+ *
+ * CertStatus ::= CHOICE {
+ *     good                [0]     IMPLICIT NULL,
+ *     revoked             [1]     IMPLICIT RevokedInfo,
+ *     unknown             [2]     IMPLICIT UnknownInfo }
+ * 
+ * RevokedInfo ::= SEQUENCE {
+ *     revocationTime              GeneralizedTime,
+ *     revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
+ * </programlisting></informalexample>
+ *
+ * Each of the pointers to output variables may be NULL to indicate
+ * that the caller is not interested in that value.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error code is returned.  If you have reached the last
+ *   CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
+ *   returned.
+ **/
+int
+gnutls_ocsp_resp_get_single (gnutls_ocsp_resp_t resp,
+                            unsigned indx,
+                            gnutls_digest_algorithm_t *digest,
+                            gnutls_datum_t *issuer_name_hash,
+                            gnutls_datum_t *issuer_key_hash,
+                            gnutls_datum_t *serial_number,
+                            int *cert_status,
+                            time_t *this_update,
+                            time_t *next_update,
+                            time_t *revocation_time,
+                            int *revocation_reason)
+{
+  gnutls_datum_t sa;
+  char name[ASN1_MAX_NAME_SIZE];
+  int ret;
+
+  snprintf (name, sizeof (name),
+           "tbsResponseData.responses.?%u.certID.hashAlgorithm.algorithm",
+           indx + 1);
+  ret = _gnutls_x509_read_value (resp->basicresp, name, &sa, 0);
+  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
+    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+  else if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = _gnutls_x509_oid2digest_algorithm (sa.data);
+  _gnutls_free_datum (&sa);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  if (digest)
+    *digest = ret;
+
+  if (issuer_name_hash)
+    {
+      snprintf (name, sizeof (name),
+               "tbsResponseData.responses.?%u.certID.issuerNameHash",
+               indx + 1);
+      ret = _gnutls_x509_read_value (resp->basicresp, name,
+                                    issuer_name_hash, 0);
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+    }
+
+  if (issuer_key_hash)
+    {
+      snprintf (name, sizeof (name),
+               "tbsResponseData.responses.?%u.certID.issuerKeyHash",
+               indx + 1);
+      ret = _gnutls_x509_read_value (resp->basicresp, name,
+                                    issuer_key_hash, 0);
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         if (issuer_name_hash)
+           gnutls_free (issuer_name_hash->data);
+         return ret;
+       }
+    }
+
+  if (serial_number)
+    {
+      snprintf (name, sizeof (name),
+               "tbsResponseData.responses.?%u.certID.serialNumber",
+               indx + 1);
+      ret = _gnutls_x509_read_value (resp->basicresp, name,
+                                    serial_number, 0);
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         if (issuer_name_hash)
+           gnutls_free (issuer_name_hash->data);
+         if (issuer_key_hash)
+           gnutls_free (issuer_key_hash->data);
+         return ret;
+       }
+    }
+
+  if (cert_status)
+    {
+      snprintf (name, sizeof (name),
+               "tbsResponseData.responses.?%u.certStatus",
+               indx + 1);
+      ret = _gnutls_x509_read_value (resp->basicresp, name, &sa, 0);
+      if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
+       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+      else if (ret < 0)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+      if (sa.size == 5 && memcmp (sa.data, "good", sa.size) == 0)
+       *cert_status = GNUTLS_OCSP_CERT_GOOD;
+      else if (sa.size == 8 && memcmp (sa.data, "revoked", sa.size) == 0)
+       *cert_status = GNUTLS_OCSP_CERT_REVOKED;
+      else if (sa.size == 8 && memcmp (sa.data, "unknown", sa.size) == 0)
+       *cert_status = GNUTLS_OCSP_CERT_UNKNOWN;
+      else
+       {
+         gnutls_assert ();
+         gnutls_free (sa.data);
+         return GNUTLS_E_ASN1_DER_ERROR;
+       }
+      gnutls_free (sa.data);
+    }
+
+  if (this_update)
+    {
+      char ttime[MAX_TIME];
+      int len;
+
+      snprintf (name, sizeof (name),
+               "tbsResponseData.responses.?%u.thisUpdate",
+               indx + 1);
+      len = sizeof (ttime) - 1;
+      ret = asn1_read_value (resp->basicresp, name, ttime, &len);
+      if (ret != ASN1_SUCCESS)
+       {
+         gnutls_assert ();
+         *this_update = (time_t) (-1);
+       }
+      else
+       *this_update = _gnutls_x509_generalTime2gtime (ttime);
+    }
+
+  if (next_update)
+    {
+      char ttime[MAX_TIME];
+      int len;
+
+      snprintf (name, sizeof (name),
+               "tbsResponseData.responses.?%u.nextUpdate",
+               indx + 1);
+      len = sizeof (ttime) - 1;
+      ret = asn1_read_value (resp->basicresp, name, ttime, &len);
+      if (ret != ASN1_SUCCESS)
+       {
+         gnutls_assert ();
+         *next_update = (time_t) (-1);
+       }
+      else
+       *next_update = _gnutls_x509_generalTime2gtime (ttime);
+    }
+
+  if (revocation_time)
+    {
+      char ttime[MAX_TIME];
+      int len;
+
+      snprintf (name, sizeof (name),
+               "tbsResponseData.responses.?%u.certStatus."
+               "revoked.revocationTime",
+               indx + 1);
+      len = sizeof (ttime) - 1;
+      ret = asn1_read_value (resp->basicresp, name, ttime, &len);
+      if (ret != ASN1_SUCCESS)
+       {
+         gnutls_assert ();
+         *revocation_time = (time_t) (-1);
+       }
+      else
+       *revocation_time = _gnutls_x509_generalTime2gtime (ttime);
+    }
+
+  /* revocation_reason */
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_resp_get_extension:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ * @indx: Specifies which extension OID to get. Use (0) to get the first one.
+ * @oid: will hold newly allocated buffer with OID of extension, may be NULL
+ * @critical: output variable with critical flag, may be NULL.
+ * @data: will hold newly allocated buffer with extension data, may be NULL
+ *
+ * This function will return all information about the requested
+ * extension in the OCSP response.  The information returned is the
+ * OID, the critical flag, and the data itself.  The extension OID
+ * will be stored as a string.  Any of @oid, @critical, and @data may
+ * be NULL which means that the caller is not interested in getting
+ * that information back.
+ *
+ * The caller needs to deallocate memory by calling gnutls_free() on
+ * @oid->data and @data->data.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error code is returned.  If you have reached the last
+ *   extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
+ *   be returned.
+ **/
+int
+gnutls_ocsp_resp_get_extension (gnutls_ocsp_resp_t resp,
+                               unsigned indx,
+                               gnutls_datum_t *oid,
+                               unsigned int *critical,
+                               gnutls_datum_t *data)
+{
+  int ret;
+  char str_critical[10];
+  char name[ASN1_MAX_NAME_SIZE];
+  int len;
+
+  if (!resp)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  snprintf (name, sizeof (name),
+           "tbsResponseData.responseExtensions.?%u.critical",
+           indx + 1);
+  len = sizeof (str_critical);
+  ret = asn1_read_value (resp->basicresp, name, str_critical, &len);
+  if (ret == ASN1_ELEMENT_NOT_FOUND)
+    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+  else if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (ret);
+    }
+
+  if (critical)
+    {
+      if (str_critical[0] == 'T')
+       *critical = 1;
+      else
+       *critical = 0;
+    }
+
+  if (oid)
+    {
+      snprintf (name, sizeof (name),
+               "tbsResponseData.responseExtensions.?%u.extnID", indx + 1);
+      ret = _gnutls_x509_read_value (resp->basicresp, name, oid, 0);
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+    }
+
+  if (data)
+    {
+      snprintf (name, sizeof (name),
+               "tbsResponseData.responseExtensions.?%u.extnValue", indx + 1);
+      ret = _gnutls_x509_read_value (resp->basicresp, name, data, 0);
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         if (oid)
+           gnutls_free (oid->data);
+         return ret;
+       }
+    }
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_resp_get_nonce:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ * @critical: whether nonce extension is marked critical
+ * @nonce: will hold newly allocated buffer with nonce data
+ *
+ * This function will return the Basic OCSP Response nonce extension
+ * data.
+ *
+ * The caller needs to deallocate memory by calling gnutls_free() on
+ * @nonce->data.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error code is returned.
+ **/
+int
+gnutls_ocsp_resp_get_nonce (gnutls_ocsp_resp_t resp,
+                           unsigned int *critical,
+                           gnutls_datum_t *nonce)
+{
+  int ret;
+  size_t l = 0;
+  gnutls_datum_t tmp;
+
+  ret = get_extension (resp->basicresp, "tbsResponseData.responseExtensions",
+                      GNUTLS_OCSP_NONCE, 0,
+                      &tmp, critical);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = _gnutls_x509_decode_octet_string (NULL, tmp.data, (size_t) tmp.size,
+                                         NULL, &l);
+  if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
+    {
+      gnutls_assert ();
+      gnutls_free (tmp.data);
+      return ret;
+    }
+
+  nonce->data = gnutls_malloc (l);
+  if (nonce->data == NULL)
+    {
+      gnutls_assert ();
+      gnutls_free (tmp.data);
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  ret = _gnutls_x509_decode_octet_string (NULL, tmp.data, (size_t) tmp.size,
+                                         nonce->data, &l);
+  gnutls_free (tmp.data);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+  nonce->size = l;
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_resp_get_signature_algorithm:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ *
+ * This function will return a value of the #gnutls_sign_algorithm_t
+ * enumeration that is the signature algorithm that has been used to
+ * sign the OCSP response.
+ *
+ * Returns: a #gnutls_sign_algorithm_t value, or a negative error code
+ *   on error.
+ **/
+int
+gnutls_ocsp_resp_get_signature_algorithm (gnutls_ocsp_resp_t resp)
+{
+  int ret;
+  gnutls_datum_t sa;
+
+  ret = _gnutls_x509_read_value (resp->basicresp,
+                                "signatureAlgorithm.algorithm", &sa, 0);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = _gnutls_x509_oid2sign_algorithm (sa.data);
+
+  _gnutls_free_datum (&sa);
+
+  return ret;
+}
+
+/**
+ * gnutls_ocsp_resp_get_signature:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ * @sig: newly allocated output buffer with signature data
+ *
+ * This function will extract the signature field of a OCSP response.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_ocsp_resp_get_signature (gnutls_ocsp_resp_t resp,
+                               gnutls_datum_t *sig)
+{
+  int ret;
+
+  if (resp == NULL || sig == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  ret = _gnutls_x509_read_value (resp->basicresp, "signature", sig, 2);
+  if (ret != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_ocsp_resp_get_certs:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ * @certs: newly allocated array with #gnutls_x509_crt_t certificates
+ * @ncerts: output variable with number of allocated certs.
+ *
+ * This function will extract the X.509 certificates found in the
+ * Basic OCSP Response.  The @certs output variable will hold a newly
+ * allocated zero-terminated array with X.509 certificates.
+ *
+ * Every certificate in the array needs to be de-allocated with
+ * gnutls_x509_crt_deinit() and the array itself must be freed using
+ * gnutls_free().
+ *
+ * Both the @certs and @ncerts variables may be NULL.  Then the
+ * function will work as normal but will not return the NULL:d
+ * information.  This can be used to get the number of certificates
+ * only, or to just get the certificate array without its size.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_ocsp_resp_get_certs (gnutls_ocsp_resp_t resp,
+                           gnutls_x509_crt_t ** certs,
+                           size_t *ncerts)
+{
+  int ret;
+  size_t ctr = 0, i;
+  gnutls_x509_crt_t *tmpcerts = NULL, *tmpcerts2;
+  gnutls_datum_t c = { NULL, 0 };
+
+  if (resp == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  tmpcerts = gnutls_malloc (sizeof (*tmpcerts));
+  if (tmpcerts == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  for (;;)
+    {
+      char name[ASN1_MAX_NAME_SIZE];
+
+      snprintf (name, sizeof (name), "certs.?%lu", ctr + 1);
+      ret = _gnutls_x509_der_encode (resp->basicresp, name, &c, 0);
+      if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
+       break;
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         goto error;
+       }
+
+      tmpcerts2 = gnutls_realloc (tmpcerts, (ctr + 2) * sizeof (*tmpcerts));
+      if (tmpcerts2 == NULL)
+       {
+         gnutls_assert ();
+         ret = GNUTLS_E_MEMORY_ERROR;
+         goto error;
+       }
+      tmpcerts = tmpcerts2;
+
+      ret = gnutls_x509_crt_init (&tmpcerts[ctr]);
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         goto error;
+       }
+      ctr++;
+
+      ret = gnutls_x509_crt_import (tmpcerts[ctr - 1], &c,
+                                   GNUTLS_X509_FMT_DER);
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         goto error;
+       }
+
+      gnutls_free (c.data);
+      c.data = NULL;
+    }
+
+  tmpcerts[ctr] = NULL;
+
+  if (ncerts)
+    *ncerts = ctr;
+  if (certs)
+    *certs = tmpcerts;
+  else
+    {
+      /* clean up memory */
+      ret = GNUTLS_E_SUCCESS;
+      goto error;
+    }
+
+  return GNUTLS_E_SUCCESS;
+
+ error:
+  gnutls_free (c.data);
+  for (i = 0; i < ctr; i++)
+    gnutls_x509_crt_deinit (tmpcerts[i]);
+  gnutls_free (tmpcerts);
+  return ret;
+}
+
+/* Search the OCSP response for a certificate matching the responderId
+   mentioned in the OCSP response. */
+static gnutls_x509_crt_t
+find_signercert (gnutls_ocsp_resp_t resp)
+{
+  int rc;
+  gnutls_x509_crt_t * certs;
+  size_t ncerts = 0, i;
+  gnutls_datum_t riddn;
+  gnutls_x509_crt_t signercert = NULL;
+
+  rc = gnutls_ocsp_resp_get_responder (resp, &riddn);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return NULL;
+    }
+
+  rc = gnutls_ocsp_resp_get_certs (resp, &certs, &ncerts);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      gnutls_free (riddn.data);
+      return NULL;
+    }
+
+  for (i = 0; i < ncerts; i++)
+    {
+      char *crtdn;
+      size_t crtdnsize = 0;
+      int cmpok;
+
+      rc = gnutls_x509_crt_get_dn (certs[i], NULL, &crtdnsize);
+      if (rc != GNUTLS_E_SHORT_MEMORY_BUFFER)
+       {
+         gnutls_assert ();
+         goto quit;
+       }
+
+      crtdn = gnutls_malloc (crtdnsize);
+      if (crtdn == NULL)
+       {
+         gnutls_assert ();
+         goto quit;
+       }
+
+      rc = gnutls_x509_crt_get_dn (certs[i], crtdn, &crtdnsize);
+      if (rc != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         gnutls_free (crtdn);
+         goto quit;
+       }
+
+      cmpok = (crtdnsize == riddn.size)
+       && memcmp (riddn.data, crtdn, crtdnsize);
+
+      gnutls_free (crtdn);
+
+      if (cmpok == 0)
+       {
+         signercert = certs[i];
+         goto quit;
+       }
+    }
+
+  gnutls_assert ();
+  signercert = NULL;
+
+ quit:
+  gnutls_free (riddn.data);
+  for (i = 0; i < ncerts; i++)
+    if (certs[i] != signercert)
+      gnutls_x509_crt_deinit (certs[i]);
+  gnutls_free (certs);
+  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)
+{
+  gnutls_datum_t sig = { NULL };
+  gnutls_datum_t data = { NULL };
+  gnutls_pubkey_t pubkey = NULL;
+  int sigalg;
+  int rc;
+
+  if (resp == NULL || signercert == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  sigalg = gnutls_ocsp_resp_get_signature_algorithm (resp);
+
+  rc = export (resp->basicresp, "tbsResponseData", &data);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      goto done;
+    }
+
+  rc = gnutls_pubkey_init (&pubkey);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      goto done;
+    }
+
+  rc = gnutls_pubkey_import_x509 (pubkey, signercert, 0);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      goto done;
+    }
+
+  rc = gnutls_ocsp_resp_get_signature (resp, &sig);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      goto done;
+    }
+
+  rc = gnutls_pubkey_verify_data2 (pubkey, sigalg, 0, &data, &sig);
+  if (rc == GNUTLS_E_PK_SIG_VERIFY_FAILED)
+    {
+      gnutls_assert ();
+      *verify = GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE;
+    }
+  else if (rc < 0)
+    {
+      gnutls_assert ();
+      goto done;
+    }
+  else
+    *verify = 0;
+
+  rc = GNUTLS_E_SUCCESS;
+
+ done:
+  gnutls_free (data.data);
+  gnutls_free (sig.data);
+  gnutls_pubkey_deinit (pubkey);
+
+  return rc;
+}
+
+/**
+ * gnutls_ocsp_resp_verify:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ * @trustlist: trust anchors as a #gnutls_x509_trust_list_t structure
+ * @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 certificate of a trusted signer.  The @trustlist should be
+ * populated with trust anchors.  The function will extract the signer
+ * certificate from the Basic OCSP Response and will verify it against
+ * the @trustlist.  A trusted signer is a certificate that is either
+ * in @trustlist, or it is signed directly by a certificate in
+ * @trustlist and has the id-ad-ocspSigning Extended Key Usage bit
+ * set.
+ *
+ * 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 (gnutls_ocsp_resp_t resp,
+                        gnutls_x509_trust_list_t trustlist,
+                        unsigned *verify,
+                        int flags)
+{
+  gnutls_x509_crt_t signercert = NULL;
+  int rc;
+
+  /* Algorithm:
+     1. Find signer cert.
+        1a. Search in OCSP response Certificate field for responderID.
+        1b. Verify that signer cert is trusted.
+        2a. It is in trustlist?
+        2b. It has OCSP key usage and directly signed by a CA in trustlist?
+     3. Verify signature of Basic Response using public key from signer cert.
+  */
+
+  signercert = find_signercert (resp);
+  if (!signercert)
+    {
+      /* XXX Search in trustlist for certificate matching
+        responderId as well? */
+      gnutls_assert ();
+      *verify = GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND;
+      rc = GNUTLS_E_SUCCESS;
+      goto done;
+    }
+
+  /* Either the signer is directly trusted (i.e., in trustlist) or it
+     is directly signed by something in trustlist and has proper OCSP
+     extkeyusage. */
+  rc = _gnutls_trustlist_inlist (trustlist, signercert);
+  if (rc < 0)
+    {
+      gnutls_assert ();
+      goto done;
+    }
+  if (rc == 1)
+    {
+      /* 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 ();
+
+      rc = gnutls_x509_trust_list_get_issuer (trustlist, signercert,
+                                             &issuer, 0);
+      if (rc != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         *verify = GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER;
+         rc = GNUTLS_E_SUCCESS;
+         goto done;
+       }
+
+      rc = gnutls_x509_crt_verify (signercert, &issuer, 1, 0, &vtmp);
+      if (rc != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         goto done;
+       }
+
+      if (vtmp != 0)
+       {
+         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 = gnutls_ocsp_resp_verify_direct (resp, signercert, verify, flags);
+
+ done:
+  gnutls_x509_crt_deinit (signercert);
+
+  return rc;
+}
diff --git a/lib/x509/ocsp_output.c b/lib/x509/ocsp_output.c
new file mode 100644
index 0000000..719ce89
--- /dev/null
+++ b/lib/x509/ocsp_output.c
@@ -0,0 +1,631 @@
+/*
+ * Copyright (C) 2011-2012 Free Software Foundation, Inc.
+ * Author: Simon Josefsson
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/* Online Certificate Status Protocol - RFC 2560
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_global.h>
+#include <gnutls_errors.h>
+#include <libtasn1.h>
+#include <gnutls_pk.h>
+#include "algorithms.h"
+
+#include <gnutls/ocsp.h>
+
+/* I18n of error codes. */
+#include "gettext.h"
+#define _(String) dgettext (PACKAGE, String)
+
+#define addf _gnutls_buffer_append_printf
+#define adds _gnutls_buffer_append_str
+
+static void
+print_req (gnutls_buffer_st * str, gnutls_ocsp_req_t req)
+{
+  int ret;
+  unsigned indx;
+
+  /* Version. */
+  {
+    int version = gnutls_ocsp_req_get_version (req);
+    if (version < 0)
+      addf (str, "error: get_version: %s\n", gnutls_strerror (version));
+    else
+      addf (str, _("\tVersion: %d\n"), version);
+  }
+
+  /* XXX requestorName */
+
+  /* requestList */
+  addf (str, "\tRequest List:\n");
+  for (indx = 0; ; indx++)
+    {
+      gnutls_digest_algorithm_t digest;
+      gnutls_datum_t in, ik, sn;
+
+      ret = gnutls_ocsp_req_get_cert_id (req, indx, &digest, &in, &ik, &sn);
+      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+       break;
+      addf (str, "\t\tCertificate ID:\n");
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         addf (str, "error: get_cert_id: %s\n",
+               gnutls_strerror (ret));
+         continue;
+       }
+      addf (str, "\t\t\tHash Algorithm: %s\n",
+           _gnutls_digest_get_name (digest));
+
+      adds (str, "\t\t\tIssuer Name Hash: ");
+      _gnutls_buffer_hexprint (str, in.data, in.size);
+      adds (str, "\n");
+
+      adds (str, "\t\t\tIssuer Key Hash: ");
+      _gnutls_buffer_hexprint (str, ik.data, ik.size);
+      adds (str, "\n");
+
+      adds (str, "\t\t\tSerial Number: ");
+      _gnutls_buffer_hexprint (str, sn.data, sn.size);
+      adds (str, "\n");
+
+      gnutls_free (in.data);
+      gnutls_free (ik.data);
+      gnutls_free (sn.data);
+
+      /* XXX singleRequestExtensions */
+    }
+
+  for (indx = 0; ; indx++)
+    {
+      gnutls_datum_t oid;
+      unsigned int critical;
+      gnutls_datum_t data;
+
+      ret = gnutls_ocsp_req_get_extension (req, indx, &oid, &critical, &data);
+      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+       break;
+      else if (ret != GNUTLS_E_SUCCESS)
+       {
+         addf (str, "error: get_extension: %s\n",
+               gnutls_strerror (ret));
+         continue;
+       }
+      if (indx == 0)
+       adds (str, "\tExtensions:\n");
+
+      if (memcmp (oid.data, GNUTLS_OCSP_NONCE, oid.size) == 0)
+       {
+         gnutls_datum_t nonce;
+         unsigned int critical;
+
+         ret = gnutls_ocsp_req_get_nonce (req, &critical, &nonce);
+         if (ret != GNUTLS_E_SUCCESS)
+           {
+             addf (str, "error: get_nonce: %s\n",
+                   gnutls_strerror (ret));
+           }
+         else
+           {
+             addf (str, "\t\tNonce%s: ", critical ? " (critical)" : "");
+             _gnutls_buffer_hexprint (str, nonce.data, nonce.size);
+             adds (str, "\n");
+             gnutls_free (nonce.data);
+           }
+       }
+      else
+       {
+         addf (str, "\t\tUnknown extension %s (%s):\n", oid.data,
+               critical ? "critical" : "not critical");
+
+         addf (str, _("\t\t\tASCII: "));
+         _gnutls_buffer_asciiprint (str, data.data, data.size);
+         addf (str, "\n");
+
+         addf (str, _("\t\t\tHexdump: "));
+         _gnutls_buffer_hexprint (str, data.data, data.size);
+         adds (str, "\n");
+       }
+
+      gnutls_free (oid.data);
+      gnutls_free (data.data);
+    }
+
+  /* XXX Signature */
+}
+
+/**
+ * gnutls_ocsp_req_print:
+ * @req: The structure to be printed
+ * @format: Indicate the format to use
+ * @out: Newly allocated datum with (0) terminated string.
+ *
+ * This function will pretty print a OCSP request, suitable for
+ * display to a human.
+ *
+ * If the format is %GNUTLS_PRINT_FULL then all fields of the request
+ * will be output, on multiple lines.
+ *
+ * The output @out->data needs to be deallocate using gnutls_free().
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_ocsp_req_print (gnutls_ocsp_req_t req,
+                       gnutls_ocsp_print_formats_t format,
+                       gnutls_datum_t * out)
+{
+  gnutls_buffer_st str;
+  int rc;
+
+  if (format != GNUTLS_OCSP_PRINT_FULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  _gnutls_buffer_init (&str);
+
+  _gnutls_buffer_append_str (&str, _("OCSP Request Information:\n"));
+
+  print_req (&str, req);
+
+  _gnutls_buffer_append_data (&str, "\0", 1);
+
+  rc = _gnutls_buffer_to_datum (&str, out);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return rc;
+    }
+
+  return GNUTLS_E_SUCCESS;
+}
+
+static void
+print_resp (gnutls_buffer_st * str, gnutls_ocsp_resp_t resp)
+{
+  int ret;
+  unsigned indx;
+
+  ret = gnutls_ocsp_resp_get_status (resp);
+  if (ret < 0)
+    {
+      addf (str, "error: ocsp_resp_get_status: %s\n",
+           gnutls_strerror (ret));
+      return;
+    }
+
+  adds (str, "\tResponse Status: ");
+  switch (ret)
+    {
+    case GNUTLS_OCSP_RESP_SUCCESSFUL:
+      adds (str, "Successful\n");
+      break;
+
+    case GNUTLS_OCSP_RESP_MALFORMEDREQUEST:
+      adds (str, "malformedRequest\n");
+      return;
+
+    case GNUTLS_OCSP_RESP_INTERNALERROR:
+      adds (str, "internalError\n");
+      return;
+
+    case GNUTLS_OCSP_RESP_TRYLATER:
+      adds (str, "tryLater\n");
+      return;
+
+    case GNUTLS_OCSP_RESP_SIGREQUIRED:
+      adds (str, "sigRequired\n");
+      return;
+
+    case GNUTLS_OCSP_RESP_UNAUTHORIZED:
+      adds (str, "unauthorized\n");
+      return;
+
+    default:
+      adds (str, "unknown\n");
+      return;
+    }
+
+  {
+    gnutls_datum_t oid;
+
+    ret = gnutls_ocsp_resp_get_response (resp, &oid, NULL);
+    if (ret < 0)
+      {
+       addf (str, "error: get_response: %s\n", gnutls_strerror (ret));
+       return;
+      }
+
+    adds (str, "\tResponse Type: ");
+#define OCSP_BASIC "1.3.6.1.5.5.7.48.1.1"
+
+    if (oid.size == sizeof (OCSP_BASIC)
+       && memcmp (oid.data, OCSP_BASIC, oid.size) == 0)
+      {
+       adds (str, "Basic OCSP Response\n");
+       gnutls_free (oid.data);
+      }
+    else
+      {
+       addf (str, "Unknown response type (%.*s)\n", oid.size, oid.data);
+       gnutls_free (oid.data);
+       return;
+      }
+  }
+
+  /* Version. */
+  {
+    int version = gnutls_ocsp_resp_get_version (resp);
+    if (version < 0)
+      addf (str, "error: get_version: %s\n", gnutls_strerror (version));
+    else
+      addf (str, _("\tVersion: %d\n"), version);
+  }
+
+  /* responderID */
+  {
+    gnutls_datum_t dn;
+
+    /* XXX byKey */
+
+    ret = gnutls_ocsp_resp_get_responder (resp, &dn);
+    if (ret < 0)
+      addf (str, "error: get_dn: %s\n", gnutls_strerror (ret));
+    else
+      {
+       addf (str, _("\tResponder ID: %.*s\n"), dn.size, dn.data);
+       gnutls_free (dn.data);
+      }
+  }
+
+  {
+    char s[42];
+    size_t max = sizeof (s);
+    struct tm t;
+    time_t tim = gnutls_ocsp_resp_get_produced (resp);
+
+    if (tim == (time_t) -1)
+      addf (str, "error: ocsp_resp_get_produced\n");
+    else if (gmtime_r (&tim, &t) == NULL)
+      addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
+    else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
+      addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
+    else
+      addf (str, _("\tProduced At: %s\n"), s);
+  }
+
+  addf (str, "\tResponses:\n");
+  for (indx = 0; ; indx++)
+    {
+      gnutls_digest_algorithm_t digest;
+      gnutls_datum_t in, ik, sn;
+      int cert_status;
+      time_t this_update;
+      time_t next_update;
+      time_t revocation_time;
+      int revocation_reason;
+
+      ret = gnutls_ocsp_resp_get_single (resp,
+                                        indx,
+                                        &digest, &in, &ik, &sn,
+                                        &cert_status,
+                                        &this_update,
+                                        &next_update,
+                                        &revocation_time,
+                                        &revocation_reason);
+      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+       break;
+      addf (str, "\t\tCertificate ID:\n");
+      if (ret != GNUTLS_E_SUCCESS)
+       {
+         addf (str, "error: get_singleresponse: %s\n",
+               gnutls_strerror (ret));
+         continue;
+       }
+      addf (str, "\t\t\tHash Algorithm: %s\n",
+           _gnutls_digest_get_name (digest));
+
+      adds (str, "\t\t\tIssuer Name Hash: ");
+      _gnutls_buffer_hexprint (str, in.data, in.size);
+      adds (str, "\n");
+
+      adds (str, "\t\t\tIssuer Key Hash: ");
+      _gnutls_buffer_hexprint (str, ik.data, ik.size);
+      adds (str, "\n");
+
+      adds (str, "\t\t\tSerial Number: ");
+      _gnutls_buffer_hexprint (str, sn.data, sn.size);
+      adds (str, "\n");
+
+      gnutls_free (in.data);
+      gnutls_free (ik.data);
+      gnutls_free (sn.data);
+
+      {
+       const char *p = NULL;
+
+       switch (cert_status)
+         {
+         case GNUTLS_OCSP_CERT_GOOD:
+           p = "good";
+           break;
+
+         case GNUTLS_OCSP_CERT_REVOKED:
+           p = "revoked";
+           break;
+
+         case GNUTLS_OCSP_CERT_UNKNOWN:
+           p = "unknown";
+           break;
+
+         default:
+           addf (str, "\t\tCertificate Status: unexpected value %d\n",
+                 cert_status);
+           break;
+         }
+
+       if (p)
+         addf (str, "\t\tCertificate Status: %s\n", p);
+      }
+
+      /* XXX revocation reason */
+
+      if (cert_status == GNUTLS_OCSP_CERT_REVOKED)
+       {
+         char s[42];
+         size_t max = sizeof (s);
+         struct tm t;
+
+         if (revocation_time == (time_t) -1)
+           addf (str, "error: revocation_time\n");
+         else if (gmtime_r (&revocation_time, &t) == NULL)
+           addf (str, "error: gmtime_r (%ld)\n",
+                 (unsigned long) revocation_time);
+         else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
+           addf (str, "error: strftime (%ld)\n",
+                 (unsigned long) revocation_time);
+         else
+           addf (str, _("\t\tRevocation time: %s\n"), s);
+      }
+
+      {
+       char s[42];
+       size_t max = sizeof (s);
+       struct tm t;
+
+       if (this_update == (time_t) -1)
+         addf (str, "error: this_update\n");
+       else if (gmtime_r (&this_update, &t) == NULL)
+         addf (str, "error: gmtime_r (%ld)\n", (unsigned long) this_update);
+       else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
+         addf (str, "error: strftime (%ld)\n", (unsigned long) this_update);
+       else
+         addf (str, _("\t\tThis Update: %s\n"), s);
+      }
+
+      {
+       char s[42];
+       size_t max = sizeof (s);
+       struct tm t;
+
+       if (next_update == (time_t) -1)
+         addf (str, "error: next_update\n");
+       else if (gmtime_r (&next_update, &t) == NULL)
+         addf (str, "error: gmtime_r (%ld)\n", (unsigned long) next_update);
+       else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
+         addf (str, "error: strftime (%ld)\n", (unsigned long) next_update);
+       else
+         addf (str, _("\t\tNext Update: %s\n"), s);
+      }
+
+      /* XXX singleRequestExtensions */
+    }
+
+  adds (str, "\tExtensions:\n");
+  for (indx = 0; ; indx++)
+    {
+      gnutls_datum_t oid;
+      unsigned int critical;
+      gnutls_datum_t data;
+
+      ret = gnutls_ocsp_resp_get_extension (resp, indx, &oid, &critical, 
&data);
+      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+       break;
+      else if (ret != GNUTLS_E_SUCCESS)
+       {
+         addf (str, "error: get_extension: %s\n",
+               gnutls_strerror (ret));
+         continue;
+       }
+
+      if (memcmp (oid.data, GNUTLS_OCSP_NONCE, oid.size) == 0)
+       {
+         gnutls_datum_t nonce;
+         unsigned int critical;
+
+         ret = gnutls_ocsp_resp_get_nonce (resp, &critical, &nonce);
+         if (ret != GNUTLS_E_SUCCESS)
+           {
+             addf (str, "error: get_nonce: %s\n",
+                   gnutls_strerror (ret));
+           }
+         else
+           {
+             addf (str, "\t\tNonce%s: ", critical ? " (critical)" : "");
+             _gnutls_buffer_hexprint (str, nonce.data, nonce.size);
+             adds (str, "\n");
+             gnutls_free (nonce.data);
+           }
+       }
+      else
+       {
+         addf (str, "\t\tUnknown extension %s (%s):\n", oid.data,
+               critical ? "critical" : "not critical");
+
+         addf (str, _("\t\t\tASCII: "));
+         _gnutls_buffer_asciiprint (str, data.data, data.size);
+         addf (str, "\n");
+
+         addf (str, _("\t\t\tHexdump: "));
+         _gnutls_buffer_hexprint (str, data.data, data.size);
+         adds (str, "\n");
+       }
+
+      gnutls_free (oid.data);
+      gnutls_free (data.data);
+    }
+
+  /* Signature. */
+  {
+    gnutls_datum_t sig;
+
+    ret = gnutls_ocsp_resp_get_signature_algorithm (resp);
+    if (ret < 0)
+      addf (str, "retor: get_signature_algorithm: %s\n",
+           gnutls_strerror (ret));
+    else
+      {
+       const char *name = gnutls_sign_algorithm_get_name (ret);
+       if (name == NULL)
+         name = _("unknown");
+       addf (str, _("\tSignature Algorithm: %s\n"), name);
+      }
+    if (ret == GNUTLS_SIGN_RSA_MD5 || ret == GNUTLS_SIGN_RSA_MD2)
+      {
+       adds (str, _("warning: signed using a broken signature "
+                    "algorithm that can be forged.\n"));
+      }
+
+    ret = gnutls_ocsp_resp_get_signature (resp, &sig);
+    if (ret < 0)
+      addf (str, "error: get_signature: %s\n", gnutls_strerror (ret));
+    else
+      {
+       adds (str, _("\tSignature:\n"));
+       _gnutls_buffer_hexdump (str, sig.data, sig.size, "\t\t");
+
+       gnutls_free (sig.data);
+      }
+  }
+
+  /* certs */
+  {
+    gnutls_x509_crt_t *certs;
+    size_t ncerts, i;
+    gnutls_datum_t out;
+
+    ret = gnutls_ocsp_resp_get_certs (resp, &certs, &ncerts);
+    if (ret < 0)
+      addf (str, "error: get_certs: %s\n", gnutls_strerror (ret));
+    else
+      {
+       for (i = 0; i < ncerts; i++)
+         {
+           size_t s = 0;
+
+           ret = gnutls_x509_crt_print (certs[i], GNUTLS_CRT_PRINT_FULL,
+                                        &out);
+           if (ret < 0)
+             addf (str, "error: crt_print: %s\n", gnutls_strerror (ret));
+           else
+             {
+               addf (str, "%.*s", out.size, out.data);
+               gnutls_free (out.data);
+             }
+
+           ret = gnutls_x509_crt_export (certs[i], GNUTLS_X509_FMT_PEM,
+                                         NULL, &s);
+           if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
+             addf (str, "error: crt_export: %s\n", gnutls_strerror (ret));
+           else
+             {
+               out.data = gnutls_malloc (s);
+               if (out.data == NULL)
+                 addf (str, "error: malloc: %s\n",
+                       gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
+               else
+                 {
+                   ret = gnutls_x509_crt_export (certs[i], GNUTLS_X509_FMT_PEM,
+                                                 out.data, &s);
+                   out.size = s;
+                   addf (str, "%.*s", out.size, out.data);
+                   gnutls_free (out.data);
+                 }
+             }
+
+           gnutls_x509_crt_deinit (certs[i]);
+         }
+       gnutls_free (certs);
+      }
+  }
+}
+
+/**
+ * gnutls_ocsp_resp_print:
+ * @resp: The structure to be printed
+ * @format: Indicate the format to use
+ * @out: Newly allocated datum with (0) terminated string.
+ *
+ * This function will pretty print a OCSP response, suitable for
+ * display to a human.
+ *
+ * If the format is %GNUTLS_PRINT_FULL then all fields of the response
+ * will be output, on multiple lines.
+ *
+ * The output @out->data needs to be deallocate using gnutls_free().
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_ocsp_resp_print (gnutls_ocsp_resp_t resp,
+                       gnutls_ocsp_print_formats_t format,
+                       gnutls_datum_t * out)
+{
+  gnutls_buffer_st str;
+  int rc;
+
+  if (format != GNUTLS_OCSP_PRINT_FULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  _gnutls_buffer_init (&str);
+
+  _gnutls_buffer_append_str (&str, _("OCSP Response Information:\n"));
+
+  print_resp (&str, resp);
+
+  _gnutls_buffer_append_data (&str, "\0", 1);
+
+  rc = _gnutls_buffer_to_datum (&str, out);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      gnutls_assert ();
+      return rc;
+    }
+
+  return GNUTLS_E_SUCCESS;
+}
diff --git a/m4/hooks.m4 b/m4/hooks.m4
index 8d80e2a..d74d92c 100644
--- a/m4/hooks.m4
+++ b/m4/hooks.m4
@@ -214,6 +214,21 @@ fi
     AC_DEFINE([ENABLE_CRYPTODEV], 1, [Enable cryptodev support])
   fi
 
+  AC_MSG_CHECKING([whether to disable OCSP support])
+  AC_ARG_ENABLE(ocsp,
+    AS_HELP_STRING([--disable-ocsp],
+                   [disable OCSP support]),
+    ac_enable_ocsp=no)
+  if test x$ac_enable_ocsp != xno; then
+   ac_enable_ocsp=yes
+   AC_MSG_RESULT(no)
+   AC_DEFINE([ENABLE_OCSP], 1, [enable OCSP support])
+  else
+   ac_full=0
+   AC_MSG_RESULT(yes)
+  fi
+  AM_CONDITIONAL(ENABLE_OCSP, test "$ac_enable_ocsp" != "no")
+
   # For storing integers in pointers without warnings
   # 
http://developer.gnome.org/doc/API/2.0/glib/glib-Type-Conversion-Macros.html#desc
   AC_CHECK_SIZEOF(void *)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 8943037..0c83548 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,5 +1,6 @@
 # List of source files which contain translatable strings.
-lib/gnutls_errors.c
 lib/gnutls_alert.c
-lib/x509/output.c
+lib/gnutls_errors.c
 lib/openpgp/output.c
+lib/x509/ocsp_output.c
+lib/x509/output.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 888a111..a23b4b8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -39,6 +39,9 @@ endif
 if ENABLE_SRP
 bin_PROGRAMS += srptool
 endif
+if ENABLE_OCSP
+bin_PROGRAMS += ocsptool
+endif
 
 if ENABLE_PKCS11
 bin_PROGRAMS += p11tool
@@ -70,6 +73,14 @@ libcmd_srp_la_CFLAGS =
 libcmd_srp_la_SOURCES = srptool.gaa srptool-gaa.h srptool-gaa.c
 endif
 
+if ENABLE_OCSP
+ocsptool_SOURCES = ocsptool.c ocsptool-common.h
+ocsptool_LDADD = ../lib/libgnutls.la libcmd-ocsp.la ../gl/libgnu.la
+noinst_LTLIBRARIES += libcmd-ocsp.la
+libcmd_ocsp_la_CFLAGS =
+libcmd_ocsp_la_SOURCES = ocsptool.gaa ocsptool-gaa.h ocsptool-gaa.c
+endif
+
 psktool_SOURCES = psk.c
 psktool_LDADD = ../lib/libgnutls.la libcmd-psk.la ../gl/libgnu.la
 noinst_LTLIBRARIES += libcmd-psk.la
@@ -148,6 +159,8 @@ psk-gaa.c: $(srcdir)/psk.gaa
        -$(GAA) $< -o psk-gaa.c -i psk-gaa.h
 srptool-gaa.c: $(srcdir)/srptool.gaa
        -$(GAA) $< -o srptool-gaa.c -i srptool-gaa.h
+ocsptool-gaa.c: $(srcdir)/ocsptool.gaa
+       -$(GAA) $< -o ocsptool-gaa.c -i ocsptool-gaa.h
 if ENABLE_PKCS11
 p11tool-gaa.c: $(srcdir)/p11tool.gaa
        -$(GAA) $< -o p11tool-gaa.c -i p11tool-gaa.h
diff --git a/src/ocsptool-common.h b/src/ocsptool-common.h
new file mode 100644
index 0000000..729d1eb
--- /dev/null
+++ b/src/ocsptool-common.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011-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/>.
+ */
+
+#ifndef OCSPTOOL_COMMON_H
+#define OCSPTOOL_COMMON_H
+
+enum
+  {
+    ACTION_NONE,
+    ACTION_REQ_INFO,
+    ACTION_RESP_INFO,
+    ACTION_VERIFY_RESP,
+    ACTION_GEN_REQ
+  };
+
+extern void ocsptool_version (void);
+
+#endif
diff --git a/src/ocsptool.c b/src/ocsptool.c
new file mode 100644
index 0000000..dde1028
--- /dev/null
+++ b/src/ocsptool.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2011-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 <ocsptool-common.h>
+#include <ocsptool-gaa.h>
+
+gaainfo info;
+FILE *outfile;
+FILE *infile;
+
+static void
+tls_log_func (int level, const char *str)
+{
+  fprintf (stderr, "|<%d>| %s", level, str);
+}
+
+static void
+request_info (void)
+{
+  gnutls_ocsp_req_t req;
+  int ret;
+  gnutls_datum_t dat;
+  size_t size;
+
+  ret = gnutls_ocsp_req_init (&req);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "ocsp_req_init: %s", gnutls_strerror (ret));
+
+  if (info.req)
+    dat.data = read_binary_file (info.req, &size);
+  else
+    dat.data = fread_file (infile, &size);
+  if (dat.data == NULL)
+    error (EXIT_FAILURE, errno, "reading request");
+  dat.size = size;
+
+  ret = gnutls_ocsp_req_import (req, &dat);
+  free (dat.data);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "importing request: %s", gnutls_strerror (ret));
+
+  ret = gnutls_ocsp_req_print (req, GNUTLS_OCSP_PRINT_FULL, &dat);
+  if (ret != 0)
+    error (EXIT_FAILURE, 0, "ocsp_req_print: %s", gnutls_strerror (ret));
+
+  printf ("%.*s", dat.size, dat.data);
+  gnutls_free (dat.data);
+
+  gnutls_ocsp_req_deinit (req);
+}
+
+static void
+response_info (void)
+{
+  gnutls_ocsp_resp_t resp;
+  int ret;
+  gnutls_datum_t dat;
+  size_t size;
+
+  ret = gnutls_ocsp_resp_init (&resp);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "ocsp_resp_init: %s", gnutls_strerror (ret));
+
+  if (info.resp)
+    dat.data = read_binary_file (info.resp, &size);
+  else
+    dat.data = fread_file (infile, &size);
+  if (dat.data == NULL)
+    error (EXIT_FAILURE, errno, "reading response");
+  dat.size = size;
+
+  ret = gnutls_ocsp_resp_import (resp, &dat);
+  free (dat.data);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "importing response: %s", gnutls_strerror (ret));
+
+  ret = gnutls_ocsp_resp_print (resp, GNUTLS_OCSP_PRINT_FULL, &dat);
+  if (ret != 0)
+    error (EXIT_FAILURE, 0, "ocsp_resp_print: %s", gnutls_strerror (ret));
+
+  printf ("%.*s", dat.size, dat.data);
+  gnutls_free (dat.data);
+
+  gnutls_ocsp_resp_deinit (resp);
+}
+
+static gnutls_x509_crt_t
+load_issuer (void)
+{
+  gnutls_x509_crt_t crt;
+  int ret;
+  gnutls_datum_t dat;
+  size_t size;
+
+  if (info.issuer == NULL)
+    error (EXIT_FAILURE, 0, "missing --load-issuer");
+
+  ret = gnutls_x509_crt_init (&crt);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
+
+  dat.data = read_binary_file (info.issuer, &size);
+  dat.size = size;
+
+  if (!dat.data)
+    error (EXIT_FAILURE, errno, "reading --load-issuer: %s", info.issuer);
+
+  ret = gnutls_x509_crt_import (crt, &dat, info.inder);
+  free (dat.data);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "importing --load-issuer: %s: %s",
+           info.issuer, gnutls_strerror (ret));
+
+  return crt;
+}
+
+static gnutls_x509_crt_t
+load_cert (void)
+{
+  gnutls_x509_crt_t crt;
+  int ret;
+  gnutls_datum_t dat;
+  size_t size;
+
+  if (info.cert == NULL)
+    error (EXIT_FAILURE, 0, "missing --load-cert");
+
+  ret = gnutls_x509_crt_init (&crt);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
+
+  dat.data = read_binary_file (info.cert, &size);
+  dat.size = size;
+
+  if (!dat.data)
+    error (EXIT_FAILURE, errno, "reading --load-cert: %s", info.cert);
+
+  ret = gnutls_x509_crt_import (crt, &dat, info.inder);
+  free (dat.data);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "importing --load-cert: %s: %s",
+           info.cert, gnutls_strerror (ret));
+
+  return crt;
+}
+
+static void
+generate_request (void)
+{
+  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 (cert);
+  gnutls_x509_crt_deinit (issuer);
+
+  if (!info.nononce)
+    {
+      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));
+
+  fwrite (dat.data, 1, dat.size, outfile);
+
+  gnutls_free (dat.data);
+
+  gnutls_ocsp_req_deinit (req);
+}
+
+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 void
+verify_response (void)
+{
+  gnutls_ocsp_resp_t resp;
+  int ret;
+  gnutls_datum_t dat;
+  size_t size;
+  gnutls_x509_crt_t *x509_ca_list = NULL;
+  unsigned int x509_ncas = 0;
+  gnutls_x509_trust_list_t list;
+  gnutls_x509_crt_t signer;
+  unsigned verify;
+
+  ret = gnutls_ocsp_resp_init (&resp);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "ocsp_resp_init: %s", gnutls_strerror (ret));
+
+  if (info.resp)
+    dat.data = read_binary_file (info.resp, &size);
+  else
+    dat.data = fread_file (infile, &size);
+  if (dat.data == NULL)
+    error (EXIT_FAILURE, errno, "reading response");
+  dat.size = size;
+
+  ret = gnutls_ocsp_resp_import (resp, &dat);
+  free (dat.data);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "importing response: %s", gnutls_strerror (ret));
+
+  if (info.trust && info.signer)
+    error (EXIT_FAILURE, 0, "cannot mix --load-trust and --load-signer");
+  else if (info.signer == NULL)
+    {
+      dat.data = read_binary_file (info.trust, &size);
+      if (dat.data == NULL)
+       error (EXIT_FAILURE, errno, "reading --load-trust: %s", info.trust);
+      dat.size = size;
+
+      ret = gnutls_x509_trust_list_init (&list, 0);
+      if (ret < 0)
+       error (EXIT_FAILURE, 0, "gnutls_x509_trust_list_init: %s",
+              gnutls_strerror (ret));
+
+      ret = gnutls_x509_crt_list_import2 (&x509_ca_list, &x509_ncas, &dat,
+                                         GNUTLS_X509_FMT_PEM, 0);
+      if (ret < 0 || x509_ncas < 1)
+       error (EXIT_FAILURE, 0, "error parsing CAs: %s",
+              gnutls_strerror (ret));
+
+      if (info.verbose)
+       {
+         unsigned int i;
+         for (i = 0; i < x509_ncas; i++)
+           {
+             gnutls_datum_t out;
+
+             ret = gnutls_x509_crt_print (x509_ca_list[i],
+                                          GNUTLS_CRT_PRINT_ONELINE, &out);
+             if (ret < 0)
+               error (EXIT_FAILURE, 0, "gnutls_x509_crt_print: %s",
+                      gnutls_strerror (ret));
+
+             printf ("Trust anchor %d: %.*s\n", i, out.size, out.data);
+             gnutls_free (out.data);
+           }
+       }
+
+      ret = gnutls_x509_trust_list_add_cas (list, x509_ca_list, x509_ncas, 0);
+      if (ret < 0)
+       error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_cas: %s",
+              gnutls_strerror (ret));
+
+      if (info.verbose)
+       fprintf (stdout, "Loaded %d trust anchors\n", x509_ncas);
+
+      ret = gnutls_ocsp_resp_verify (resp, list, &verify, 0);
+      if (ret < 0)
+       error (EXIT_FAILURE, 0, "gnutls_ocsp_resp_verify: %s",
+              gnutls_strerror (ret));
+    }
+  else if (info.trust == NULL)
+    {
+      ret = gnutls_x509_crt_init (&signer);
+      if (ret < 0)
+       error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));
+
+      dat.data = read_binary_file (info.signer, &size);
+      if (dat.data == NULL)
+       error (EXIT_FAILURE, errno, "reading --load-signer: %s", info.signer);
+      dat.size = size;
+
+      ret = gnutls_x509_crt_import (signer, &dat, info.inder);
+      free (dat.data);
+      if (ret < 0)
+       error (EXIT_FAILURE, 0, "importing --load-signer: %s: %s",
+              info.signer, gnutls_strerror (ret));
+
+      if (info.verbose)
+       {
+         gnutls_datum_t out;
+
+         ret = gnutls_x509_crt_print (signer, GNUTLS_CRT_PRINT_ONELINE, &out);
+         if (ret < 0)
+           error (EXIT_FAILURE, 0, "gnutls_x509_crt_print: %s",
+                  gnutls_strerror (ret));
+
+         printf ("Signer: %.*s\n", out.size, out.data);
+         gnutls_free (out.data);
+       }
+
+      ret = gnutls_ocsp_resp_verify_direct (resp, signer, &verify, 0);
+      if (ret < 0)
+       error (EXIT_FAILURE, 0, "gnutls_ocsp_resp_verify_direct: %s",
+              gnutls_strerror (ret));
+    }
+  else
+    error (EXIT_FAILURE, 0, "missing --load-trust or --load-signer");
+
+  printf ("Verifying OCSP Response: ");
+  print_verify_res (verify);
+  printf (".\n");
+
+  gnutls_ocsp_resp_deinit (resp);
+}
+
+int
+main (int argc, char **argv)
+{
+  int ret;
+
+  set_program_name (argv[0]);
+
+  if ((ret = gnutls_global_init ()) < 0)
+    error (EXIT_FAILURE, 0, "global_init: %s", gnutls_strerror (ret));
+
+  if (gaa (argc, argv, &info) != -1)
+    {
+      fprintf (stderr, "Try `%s --help' for more information.\n",
+               program_name);
+      exit (EXIT_FAILURE);
+    }
+
+  gnutls_global_set_log_function (tls_log_func);
+  gnutls_global_set_log_level (info.debug);
+
+  if (info.outfile)
+    {
+      outfile = fopen (info.outfile, "wb");
+      if (outfile == NULL)
+        error (EXIT_FAILURE, errno, "%s", info.outfile);
+    }
+  else
+    outfile = stdout;
+
+  if (info.infile)
+    {
+      infile = fopen (info.infile, "rb");
+      if (infile == NULL)
+        error (EXIT_FAILURE, errno, "%s", info.infile);
+    }
+  else
+    infile = stdin;
+
+  if (info.inder)
+    info.inder = GNUTLS_X509_FMT_DER;
+  else
+    info.inder = GNUTLS_X509_FMT_PEM;
+
+  switch (info.action)
+    {
+    case ACTION_REQ_INFO:
+      request_info ();
+      break;
+
+    case ACTION_RESP_INFO:
+      response_info ();
+      break;
+
+    case ACTION_GEN_REQ:
+      generate_request ();
+      break;
+
+    case ACTION_VERIFY_RESP:
+      verify_response ();
+      break;
+
+    default:
+      gaa_help();
+    }
+
+  return 0;
+}
+
+void
+ocsptool_version (void)
+{
+  const char *p = PACKAGE_NAME;
+  if (strcmp (gnutls_check_version (NULL), PACKAGE_VERSION) != 0)
+    p = PACKAGE_STRING;
+  version_etc (stdout, "ocsptool", p, gnutls_check_version (NULL),
+               "Simon Josefsson", (char *) NULL);
+}
diff --git a/src/ocsptool.gaa b/src/ocsptool.gaa
new file mode 100644
index 0000000..1f0195d
--- /dev/null
+++ b/src/ocsptool.gaa
@@ -0,0 +1,76 @@
+#{
+
+/* C declarations */
+
+#include <config.h>
+#ifdef _WIN32
+# include <io.h>
+#endif
+
+#include "ocsptool-common.h"
+
+#}
+
+helpnode "Ocsptool help\nUsage : ocsptool [options]"
+
+#int action;
+
+option (e, verify-response) { $action = ACTION_VERIFY_RESP; } "Verify 
response."
+
+option (i, request-info) { $action = ACTION_REQ_INFO; } "Print information on 
a OCSP request."
+
+option (j, response-info) { $action = ACTION_RESP_INFO; } "Print information 
on a OCSP response."
+
+option (q, generate-request) { $action = ACTION_GEN_REQ; } "Generate a OCSP 
request."
+
+#int nononce;
+option (no-nonce) { $nononce = 1 } "don't add nonce to OCSP request."
+
+#char *issuer;
+option (load-issuer) STR "FILE" { $issuer = $1 } "read issuer certificate from 
FILE."
+
+#char *cert;
+option (load-cert) STR "FILE" { $cert = $1 } "read certificate to check from 
FILE."
+
+#char *trust;
+option (load-trust) STR "FILE" { $trust = $1 } "read OCSP trust anchors from 
FILE."
+
+#char *signer;
+option (load-signer) STR "FILE" { $signer = $1 } "read OCSP response signer 
from FILE."
+
+#int inder;
+option (inder) { $inder=1 } "Use DER format for input certificates."
+
+#char *req;
+option (Q, load-request) STR "FILE" { $req = $1 } "read DER encoded OCSP 
request from FILE."
+
+#char *resp;
+option (S, load-response) STR "FILE" { $resp = $1 } "read DER encoded OCSP 
response from FILE."
+
+#char *outfile;
+option (outfile) STR "FILE" { $outfile = $1 } "Output file."
+
+#char *infile;
+option (infile) STR "FILE" { $infile = $1 } "Input file."
+
+#int verbose;
+option (V, verbose) { $verbose = 1 } "More verbose output."
+
+#int debug;
+option (d, debug) INT "integer" { $debug = $1 } "Enable debugging"
+
+option (v, version) { ocsptool_version(); exit(0); } "prints the program's 
version number"
+option (h, help) { gaa_help(); exit(0); } "shows this help text"
+
+init { $action = ACTION_NONE;
+       $nononce = 0;
+       $inder = 0;
+       $issuer = NULL;
+       $cert = NULL;
+       $trust = NULL;
+       $req = NULL;
+       $resp = NULL;
+       $outfile = NULL;
+       $infile = NULL;
+       $verbose = 0;
+       $debug = 0; }
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f7ab496..70f8946 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -68,6 +68,10 @@ ctests = mini-deflate simple gc set_pkcs12_cred certder 
certuniqueid \
         mini-x509-rehandshake rng-fork mini-eagain-dtls        \
         x509cert x509cert-tl infoaccess rsa-encrypt-decrypt
 
+if ENABLE_OCSP
+ctests += ocsp
+endif
+
 if ENABLE_OPENSSL
 ctests +=  openssl
 openssl_LDADD = $(LDADD) ../extra/libgnutls-openssl.la
diff --git a/tests/ocsp.c b/tests/ocsp.c
new file mode 100644
index 0000000..7f4235a
--- /dev/null
+++ b/tests/ocsp.c
@@ -0,0 +1,1480 @@
+/*
+ * Copyright (C) 2011-2012 Free Software Foundation, Inc.
+ *
+ * Author: Simon Josefsson
+ *
+ * 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 GnuTLS; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/ocsp.h>
+#include <gnutls/x509.h>
+
+#include "utils.h"
+
+/* sample request */
+
+static void
+tls_log_func (int level, const char *str)
+{
+  fprintf (stderr, "|<%d>| %s", level, str);
+}
+
+#define REQ1 
"\x30\x67\x30\x65\x30\x3e\x30\x3c\x30\x3a\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14\x13\x9d\xa0\x9e\xf4\x32\xab\x8f\xe2\x89\x56\x67\xfa\xd0\xd4\xe3\x35\x86\x71\xb9\x04\x14\x5d\xa7\xdd\x70\x06\x51\x32\x7e\xe7\xb6\x6d\xb3\xb5\xe5\xe0\x60\xea\x2e\x4d\xef\x02\x01\x1d\xa2\x23\x30\x21\x30\x1f\x06\x09\x2b\x06\x01\x05\x05\x07\x30\x01\x02\x04\x12\x04\x10\x35\xc5\xe3\x50\xc3\xcf\x04\x33\xcc\x9e\x06\x3a\x9a\x18\x80\xcc"
+
+static const gnutls_datum_t req1 =
+  { (unsigned char *) REQ1, sizeof (REQ1) - 1 };
+
+#define REQ1INFO                                                       \
+  "OCSP Request Information:\n"                                                
\
+  "    Version: 1\n"                                                   \
+  "    Request List:\n"                                                \
+  "            Certificate ID:\n"                                      \
+  "                    Hash Algorithm: SHA1\n"                         \
+  "                    Issuer Name Hash: 
139da09ef432ab8fe2895667fad0d4e3358671b9\n" \
+  "                    Issuer Key Hash: 
5da7dd700651327ee7b66db3b5e5e060ea2e4def\n" \
+  "                    Serial Number: 1d\n"                            \
+  "    Extensions:\n"                                                  \
+  "            Nonce: 35c5e350c3cf0433cc9e063a9a1880cc\n"
+
+#define REQ1NONCE 
"\x04\x10\x35\xc5\xe3\x50\xc3\xcf\x04\x33\xcc\x9e\x06\x3a\x9a\x18\x80\xcc"
+
+#define REQ1INH 
"\x13\x9d\xa0\x9e\xf4\x32\xab\x8f\xe2\x89\x56\x67\xfa\xd0\xd4\xe3\x35\x86\x71\xb9"
+#define REQ1IKH 
"\x5d\xa7\xdd\x70\x06\x51\x32\x7e\xe7\xb6\x6d\xb3\xb5\xe5\xe0\x60\xea\x2e\x4d\xef"
+#define REQ1SN "\x1d"
+
+/* sample response */
+
+#define RESP1 "\x30\x03\x0a\x01\x01"
+
+static const gnutls_datum_t resp1 =
+  { (unsigned char*) RESP1, sizeof (RESP1) - 1 };
+
+#define RESP1INFO                                                      \
+  "OCSP Response Information:\n"                                       \
+  "    Response Status: malformedRequest\n"
+
+#define RESP2 
"\x30\x82\x06\x8C\x0A\x01\x00\xA0\x82\x06\x85\x30\x82\x06\x81\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x01\x04\x82\x06\x72\x30\x82\x06\x6E\x30\x82\x01\x07\xA1\x69\x30\x67\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x43\x48\x31\x19\x30\x17\x06\x03\x55\x04\x0A\x13\x10\x4C\x69\x6E\x75\x78\x20\x73\x74\x72\x6F\x6E\x67\x53\x77\x61\x6E\x31\x1F\x30\x1D\x06\x03\x55\x04\x0B\x13\x16\x4F\x43\x53\x50\x20\x53\x69\x67\x6E\x69\x6E\x67\x20\x41\x75\x74\x68\x6F\x72\x69\x74\x79\x31\x1C\x30\x1A\x06\x03\x55\x04\x03\x13\x13\x6F\x63\x73\x70\x2E\x73\x74\x72\x6F\x6E\x67\x73\x77\x61\x6E\x2E\x6F\x72\x67\x18\x0F\x32\x30\x31\x31\x30\x39\x32\x37\x30\x39\x35\x34\x32\x38\x5A\x30\x64\x30\x62\x30\x3A\x30\x09\x06\x05\x2B\x0E\x03\x02\x1A\x05\x00\x04\x14\x13\x9D\xA0\x9E\xF4\x32\xAB\x8F\xE2\x89\x56\x67\xFA\xD0\xD4\xE3\x35\x86\x71\xB9\x04\x14\x5D\xA7\xDD\x70\x06\x51\x32\x7E\xE7\xB6\x6D\xB3\xB5\xE5\xE0\x60\xEA\x2E\x4D\xEF\x02\x01\x1D\x80\x00\x18\x0F\x32\x30\x31\x31\x30\x39\x32\x37\x30\x39\x35\x34\x32\x38\x5A\xA0\x11\x18\x0F\x32\x30\x31\x31\x30\x39\x32\x37\x30\x39\x35\x39\x32\x38\x5A\xA1\x23\x30\x21\x30\x1F\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x02\x04\x12\x04\x10\x16\x89\x7D\x91\x3A\xB5\x25\xA4\x45\xFE\xC9\xFD\xC2\xE5\x08\xA4\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x03\x82\x01\x01\x00\x4E\xAD\x6B\x2B\xF7\xF2\xBF\xA9\x23\x1E\x3A\x0B\x06\xDB\x55\x53\x2B\x64\x54\x11\x32\xBF\x60\xF7\x4F\xE0\x8E\x9B\xA0\xA2\x4C\x79\xC3\x2A\xE0\x43\xF7\x40\x1A\xDC\xB9\xB4\x25\xEF\x48\x01\x97\x8C\xF5\x1E\xDB\xD1\x30\x37\x73\x69\xD6\xA7\x7A\x2D\x8E\xDE\x5C\xAA\xEA\x39\xB9\x52\xAA\x25\x1E\x74\x7D\xF9\x78\x95\x8A\x92\x1F\x98\x21\xF4\x60\x7F\xD3\x28\xEE\x47\x9C\xBF\xE2\x5D\xF6\x3F\x68\x0A\xD6\xFF\x08\xC1\xDC\x95\x1E\x29\xD7\x3E\x85\xD5\x65\xA4\x4B\xC0\xAF\xC3\x78\xAB\x06\x98\x88\x19\x8A\x64\xA6\x83\x91\x87\x13\xDB\x17\xCC\x46\xBD\xAB\x4E\xC7\x16\xD1\xF8\x35\xFD\x27\xC8\xF6\x6B\xEB\x37\xB8\x08\x6F\xE2\x6F\xB4\x7E\xD5\x68\xDB\x7F\x5D\x5E\x36\x38\xF2\x77\x59\x13\xE7\x3E\x4D\x67\x5F\xDB\xA2\xF5\x5D\x7C\xBF\xBD\xB5\x37\x33\x51\x36\x63\xF8\x21\x1E\xFC\x73\x8F\x32\x69\xBB\x97\xA7\xBD\xF1\xB6\xE0\x40\x09\x68\xEA\xD5\x93\xB8\xBB\x39\x8D\xA8\x16\x1B\xBF\x04\x7A\xBC\x18\x43\x01\xE9\x3C\x19\x5C\x4D\x4B\x98\xD8\x23\x37\x39\xA4\xC4\xDD\xED\x9C\xEC\x37\xAB\x66\x44\x9B\xE7\x5B\x5D\x32\xA2\xDB\xA6\x0B\x3B\x8C\xE1\xF5\xDB\xCB\x7D\x58\xA0\x82\x04\x4B\x30\x82\x04\x47\x30\x82\x04\x43\x30\x82\x03\x2B\xA0\x03\x02\x01\x02\x02\x01\x1E\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0B\x05\x00\x30\x45\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x43\x48\x31\x19\x30\x17\x06\x03\x55\x04\x0A\x13\x10\x4C\x69\x6E\x75\x78\x20\x73\x74\x72\x6F\x6E\x67\x53\x77\x61\x6E\x31\x1B\x30\x19\x06\x03\x55\x04\x03\x13\x12\x73\x74\x72\x6F\x6E\x67\x53\x77\x61\x6E\x20\x52\x6F\x6F\x74\x20\x43\x41\x30\x1E\x17\x0D\x30\x39\x31\x31\x32\x34\x31\x32\x35\x31\x35\x33\x5A\x17\x0D\x31\x34\x31\x31\x32\x33\x31\x32\x35\x31\x35\x33\x5A\x30\x67\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x43\x48\x31\x19\x30\x17\x06\x03\x55\x04\x0A\x13\x10\x4C\x69\x6E\x75\x78\x20\x73\x74\x72\x6F\x6E\x67\x53\x77\x61\x6E\x31\x1F\x30\x1D\x06\x03\x55\x04\x0B\x13\x16\x4F\x43\x53\x50\x20\x53\x69\x67\x6E\x69\x6E\x67\x20\x41\x75\x74\x68\x6F\x72\x69\x74\x79\x31\x1C\x30\x1A\x06\x03\x55\x04\x03\x13\x13\x6F\x63\x73\x70\x2E\x73\x74\x72\x6F\x6E\x67\x73\x77\x61\x6E\x2E\x6F\x72\x67\x30\x82\x01\x22\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x82\x01\x0F\x00\x30\x82\x01\x0A\x02\x82\x01\x01\x00\xBC\x05\x3E\x4B\xBE\xC6\xB1\x33\x48\x0E\xC3\xD4\x0C\xEF\x83\x0B\xBD\xBC\x57\x5F\x14\xEF\xF5\x6D\x0B\xFF\xFA\x01\x9C\xFA\x21\x6D\x5C\xAE\x79\x29\x74\xFE\xBD\xAB\x70\x87\x98\x6B\x48\x35\x79\xE3\xE0\xC1\x14\x41\x1F\x0A\xF7\xE7\xA3\xA6\xDA\x6B\xFF\xCD\x74\xE9\x95\x00\x38\xAA\xD6\x3A\x60\xC6\x64\xA1\xE6\x02\x39\x58\x4E\xFD\xF2\x78\x08\x63\xB6\xD7\x7A\x96\x79\x62\x18\x39\xEE\x27\x8D\x3B\xA2\x3D\x48\x88\xDB\x43\xD6\x6A\x77\x20\x6A\x27\x39\x50\xE0\x02\x50\x19\xF2\x7A\xCF\x78\x23\x99\x01\xD4\xE5\xB1\xD1\x31\xE6\x6B\x84\xAF\xD0\x77\x41\x46\x85\xB0\x3B\xE6\x6A\x00\x0F\x3B\x7E\x95\x7F\x59\xA8\x22\xE8\x49\x49\x05\xC8\xCB\x6C\xEE\x47\xA7\x2D\xC9\x74\x5B\xEB\x8C\xD5\x99\xC2\xE2\x70\xDB\xEA\x87\x43\x84\x0E\x4F\x83\x1C\xA6\xEB\x1F\x22\x38\x17\x69\x9B\x72\x12\x95\x48\x71\xB2\x7B\x92\x73\x52\xAB\xE3\x1A\xA5\xD3\xF4\x44\x14\xBA\xC3\x35\xDA\x91\x6C\x7D\xB4\xC2\x00\x07\xD8\x0A\x51\xF1\x0D\x4C\xD9\x7A\xD1\x99\xE6\xA8\x8D\x0A\x80\xA8\x91\xDD\x8A\xA2\x6B\xF6\xDB\xB0\x3E\xC9\x71\xA9\xE0\x39\xC3\xA3\x58\x0D\x87\xD0\xB2\xA7\x9C\xB7\x69\x02\x03\x01\x00\x01\xA3\x82\x01\x1A\x30\x82\x01\x16\x30\x09\x06\x03\x55\x1D\x13\x04\x02\x30\x00\x30\x0B\x06\x03\x55\x1D\x0F\x04\x04\x03\x02\x03\xA8\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\x34\x91\x6E\x91\x32\xBF\x35\x25\x43\xCC\x28\x74\xEF\x82\xC2\x57\x92\x79\x13\x73\x30\x6D\x06\x03\x55\x1D\x23\x04\x66\x30\x64\x80\x14\x5D\xA7\xDD\x70\x06\x51\x32\x7E\xE7\xB6\x6D\xB3\xB5\xE5\xE0\x60\xEA\x2E\x4D\xEF\xA1\x49\xA4\x47\x30\x45\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x43\x48\x31\x19\x30\x17\x06\x03\x55\x04\x0A\x13\x10\x4C\x69\x6E\x75\x78\x20\x73\x74\x72\x6F\x6E\x67\x53\x77\x61\x6E\x31\x1B\x30\x19\x06\x03\x55\x04\x03\x13\x12\x73\x74\x72\x6F\x6E\x67\x53\x77\x61\x6E\x20\x52\x6F\x6F\x74\x20\x43\x41\x82\x01\x00\x30\x1E\x06\x03\x55\x1D\x11\x04\x17\x30\x15\x82\x13\x6F\x63\x73\x70\x2E\x73\x74\x72\x6F\x6E\x67\x73\x77\x61\x6E\x2E\x6F\x72\x67\x30\x13\x06\x03\x55\x1D\x25\x04\x0C\x30\x0A\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x09\x30\x39\x06\x03\x55\x1D\x1F\x04\x32\x30\x30\x30\x2E\xA0\x2C\xA0\x2A\x86\x28\x68\x74\x74\x70\x3A\x2F\x2F\x63\x72\x6C\x2E\x73\x74\x72\x6F\x6E\x67\x73\x77\x61\x6E\x2E\x6F\x72\x67\x2F\x73\x74\x72\x6F\x6E\x67\x73\x77\x61\x6E\x2E\x63\x72\x6C\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0B\x05\x00\x03\x82\x01\x01\x00\x6D\x78\xD7\x66\x90\xA6\xEB\xDD\xB5\x09\x48\xA4\xDA\x27\xFA\xAC\xB1\xBC\x8F\x8C\xBE\xCC\x8C\x09\xA2\x40\x0D\x6C\x4A\xAE\x72\x22\x1E\xC8\xAF\x6D\xF1\x12\xAF\xD7\x40\x51\x79\xD4\xDD\xB2\x0C\xDB\x97\x84\xB6\x24\xD5\xF5\xA8\xBB\xC0\x4B\xF9\x7F\x71\xF7\xB0\x65\x42\x4A\x7D\xFE\x76\x7E\x05\xD2\x46\xB8\x7D\xB3\x39\x4C\x5C\xB1\xFA\xB9\xEE\x3B\x70\x33\x39\x57\x1A\xB9\x95\x51\x33\x00\x25\x1B\x4C\xAA\xB4\xA7\x55\xAF\x63\x6D\x6F\x88\x17\x6A\x7F\xB0\x97\xDE\x49\x14\x6A\x27\x6A\xB0\x42\x80\xD6\xA6\x9B\xEF\x04\x5E\x11\x7D\xD5\x8E\x54\x20\xA2\x76\xD4\x66\x58\xAC\x9C\x12\xD3\xF5\xCA\x54\x98\xCA\x21\xEC\xC1\x55\xA1\x2F\x68\x0B\x5D\x04\x50\xD2\x5E\x70\x25\xD8\x13\xD9\x44\x51\x0E\x8A\x42\x08\x18\x84\xE6\x61\xCE\x5A\x7D\x7B\x81\x35\x90\xC3\xD4\x9D\x19\xB6\x37\xEE\x8F\x63\x5C\xDA\xD8\xF0\x64\x60\x39\xEB\x9B\x1C\x54\x66\x75\x76\xB5\x0A\x58\xB9\x3F\x91\xE1\x21\x9C\xA0\x50\x15\x97\xB6\x7E\x41\xBC\xD0\xC4\x21\x4C\xF5\xD7\xF0\x13\xF8\x77\xE9\x74\xC4\x8A\x0E\x20\x17\x32\xAE\x38\xC2\xA5\xA8\x62\x85\x17\xB1\xA2\xD3\x22\x9F\x95\xB7\xA3\x4C"
+
+#define RESP2INFO                              \
+  "OCSP Response Information:\n"               \
+  "    Response Status: Successful\n"          \
+  "    Response Type: Basic OCSP Response\n"   \
+  "    Version: 1\n" \
+  "    Responder ID: C=CH,O=Linux strongSwan,OU=OCSP Signing 
Authority,CN=ocsp.strongswan.org\n" \
+  "    Produced At: Tue Sep 27 09:54:28 UTC 2011\n" \
+  "    Responses:\n" \
+  "            Certificate ID:\n" \
+  "                    Hash Algorithm: SHA1\n" \
+  "                    Issuer Name Hash: 
139da09ef432ab8fe2895667fad0d4e3358671b9\n" \
+  "                    Issuer Key Hash: 
5da7dd700651327ee7b66db3b5e5e060ea2e4def\n" \
+  "                    Serial Number: 1d\n" \
+  "            Certificate Status: good\n" \
+  "            This Update: Tue Sep 27 09:54:28 UTC 2011\n" \
+  "            Next Update: Tue Sep 27 09:59:28 UTC 2011\n" \
+  "    Extensions:\n" \
+  "            Nonce: 16897d913ab525a445fec9fdc2e508a4\n" \
+  "    Signature Algorithm: RSA-SHA1\n" \
+  "    Signature:\n" \
+  "            4e:ad:6b:2b:f7:f2:bf:a9:23:1e:3a:0b:06:db:55:53\n" \
+  "            2b:64:54:11:32:bf:60:f7:4f:e0:8e:9b:a0:a2:4c:79\n" \
+  "            c3:2a:e0:43:f7:40:1a:dc:b9:b4:25:ef:48:01:97:8c\n" \
+  "            f5:1e:db:d1:30:37:73:69:d6:a7:7a:2d:8e:de:5c:aa\n" \
+  "            ea:39:b9:52:aa:25:1e:74:7d:f9:78:95:8a:92:1f:98\n" \
+  "            21:f4:60:7f:d3:28:ee:47:9c:bf:e2:5d:f6:3f:68:0a\n" \
+  "            d6:ff:08:c1:dc:95:1e:29:d7:3e:85:d5:65:a4:4b:c0\n" \
+  "            af:c3:78:ab:06:98:88:19:8a:64:a6:83:91:87:13:db\n" \
+  "            17:cc:46:bd:ab:4e:c7:16:d1:f8:35:fd:27:c8:f6:6b\n" \
+  "            eb:37:b8:08:6f:e2:6f:b4:7e:d5:68:db:7f:5d:5e:36\n" \
+  "            38:f2:77:59:13:e7:3e:4d:67:5f:db:a2:f5:5d:7c:bf\n" \
+  "            bd:b5:37:33:51:36:63:f8:21:1e:fc:73:8f:32:69:bb\n" \
+  "            97:a7:bd:f1:b6:e0:40:09:68:ea:d5:93:b8:bb:39:8d\n" \
+  "            a8:16:1b:bf:04:7a:bc:18:43:01:e9:3c:19:5c:4d:4b\n" \
+  "            98:d8:23:37:39:a4:c4:dd:ed:9c:ec:37:ab:66:44:9b\n" \
+  "            e7:5b:5d:32:a2:db:a6:0b:3b:8c:e1:f5:db:cb:7d:58\n"
+  /* cut */
+
+static const gnutls_datum_t resp2 =
+  { (unsigned char*) RESP2, sizeof (RESP2) - 1 };
+
+static unsigned char issuer_pem[] =
+  "-----BEGIN CERTIFICATE-----\n"
+  "MIIDuDCCAqCgAwIBAgIBADANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJDSDEZ\n"
+  "MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS\n"
+  "b290IENBMB4XDTA0MDkxMDEwMDExOFoXDTE5MDkwNzEwMDExOFowRTELMAkGA1UE\n"
+  "BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xGzAZBgNVBAMTEnN0cm9u\n"
+  "Z1N3YW4gUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/y\n"
+  "X2LqPVZuWLPIeknK86xhz6ljd3NNhC2z+P1uoCP3sBMuZiZQEjFzhnKcbXxCeo2f\n"
+  "FnvhOOjrrisSuVkzuu82oxXD3fIkzuS7m9V4E10EZzgmKWIf+WuNRfbgAuUINmLc\n"
+  "4YGAXBQLPyzpP4Ou48hhz/YQo58Bics6PHy5v34qCVROIXDvqhj91P8g+pS+F21/\n"
+  "7P+CH2jRcVIEHZtG8M/PweTPQ95dPzpYd2Ov6SZ/U7EWmbMmT8VcUYn1aChxFmy5\n"
+  "gweVBWlkH6MP+1DeE0/tL5c87xo5KCeGK8Tdqpe7sBRC4pPEEHDQciTUvkeuJ1Pr\n"
+  "K+1LwdqRxo7HgMRiDw8CAwEAAaOBsjCBrzASBgNVHRMBAf8ECDAGAQH/AgEBMAsG\n"
+  "A1UdDwQEAwIBBjAdBgNVHQ4EFgQUXafdcAZRMn7ntm2zteXgYOouTe8wbQYDVR0j\n"
+  "BGYwZIAUXafdcAZRMn7ntm2zteXgYOouTe+hSaRHMEUxCzAJBgNVBAYTAkNIMRkw\n"
+  "FwYDVQQKExBMaW51eCBzdHJvbmdTd2FuMRswGQYDVQQDExJzdHJvbmdTd2FuIFJv\n"
+  "b3QgQ0GCAQAwDQYJKoZIhvcNAQELBQADggEBACOSmqEBtBLR9aV3UyCI8gmzR5in\n"
+  "Lte9aUXXS+qis6F2h2Stf4sN+Nl6Gj7REC6SpfEH4wWdwiUL5J0CJhyoOjQuDl3n\n"
+  "1Dw3dE4/zqMZdyDKEYTU75TmvusNJBdGsLkrf7EATAjoi/nrTOYPPhSUZvPp/D+Y\n"
+  "vORJ9Ej51GXlK1nwEB5iA8+tDYniNQn6BD1MEgIejzK+fbiy7braZB1kqhoEr2Si\n"
+  "7luBSnU912sw494E88a2EWbmMvg2TVHPNzCpVkpNk7kifCiwmw9VldkqYy9y/lCa\n"
+  "Epyp7lTfKw7cbD04Vk8QJW782L6Csuxkl346b17wmOqn8AZips3tFsuAY3w=\n"
+  "-----END CERTIFICATE-----\n";
+const gnutls_datum_t issuer_data = { issuer_pem, sizeof (issuer_pem) };
+
+static unsigned char subject_pem[] =
+  "-----BEGIN CERTIFICATE-----\n"
+  "MIIEIjCCAwqgAwIBAgIBHTANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJDSDEZ\n"
+  "MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS\n"
+  "b290IENBMB4XDTA5MDgyNzEwNDQ1MVoXDTE0MDgyNjEwNDQ1MVowWjELMAkGA1UE\n"
+  "BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xETAPBgNVBAsTCFJlc2Vh\n"
+  "cmNoMR0wGwYDVQQDFBRjYXJvbEBzdHJvbmdzd2FuLm9yZzCCASIwDQYJKoZIhvcN\n"
+  "AQEBBQADggEPADCCAQoCggEBANBdWU+BF7x4lyo+xHnr4UAOU89yQQuT5vdPoXzx\n"
+  "6kRPsjYAuuktgXR+SaLkQHw/YRgDPSKj5nzmmlOQf/rWRr+8O2q+C92aUICmkNvZ\n"
+  "Gamo5w2WlOMZ6T5dk2Hv+QM6xT/GzWyVr1dMYu/7tywD1Bw7aW/HqkRESDu6q95V\n"
+  "Wu+Lzg6XlxCNEez0YsZrN/fC6BL2qzKAqMBbIHFW8OOnh+nEY4IF5AzkZnFrw12G\n"
+  "I72Z882pw97lyKwZhSz/GMQFBJx+rnNdw5P1IJwTlG5PUdoDCte/Mcr1iiA+zOov\n"
+  "x55x1GoGxduoXWU5egrf1MtalRf9Pc8Xr4q3WEKTAmsZrVECAwEAAaOCAQYwggEC\n"
+  "MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgOoMB0GA1UdDgQWBBQfoamI2WSMtaCiVGQ5\n"
+  "tPI9dF1ufDBtBgNVHSMEZjBkgBRdp91wBlEyfue2bbO15eBg6i5N76FJpEcwRTEL\n"
+  "MAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xGzAZBgNVBAMT\n"
+  "EnN0cm9uZ1N3YW4gUm9vdCBDQYIBADAfBgNVHREEGDAWgRRjYXJvbEBzdHJvbmdz\n"
+  "d2FuLm9yZzA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vY3JsLnN0cm9uZ3N3YW4u\n"
+  "b3JnL3N0cm9uZ3N3YW4uY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQC8pqX3KrSzKeul\n"
+  "GdzydAV4hGwYB3WiB02oJ2nh5MJBu7J0Kn4IVkvLUHSSZhSRxx55tQZfdYqtXVS7\n"
+  "ZuyG+6rV7sb595SIRwfkLAdjbvv0yZIl4xx8j50K3yMR+9aXW1NSGPEkb8BjBUMr\n"
+  "F2kjGTOqomo8OIzyI369z9kJrtEhnS37nHcdpewZC1wHcWfJ6wd9wxmz2dVXmgVQ\n"
+  "L2BjXd/BcpLFaIC4h7jMXQ5FURjnU7K9xSa4T8PpR6FrQhOcIYBXAp94GiM8JqmK\n"
+  "ZBGUpeP+3cy4i3DV18Kyr64Q4XZlzhZClNE43sgMqiX88dc3znpDzT7T51j+d+9k\n"
+  "Rf5Z0GOR\n"
+  "-----END CERTIFICATE-----\n";
+const gnutls_datum_t subject_data = { subject_pem, sizeof (subject_pem) };
+
+/* For testing verify functions. */
+
+#define BLOG_RESP 
"\x30\x82\x06\xF8\x0A\x01\x00\xA0\x82\x06\xF1\x30\x82\x06\xED\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x01\x04\x82\x06\xDE\x30\x82\x06\xDA\x30\x82\x01\x25\xA1\x7E\x30\x7C\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x41\x55\x31\x0C\x30\x0A\x06\x03\x55\x04\x08\x13\x03\x4E\x53\x57\x31\x0F\x30\x0D\x06\x03\x55\x04\x07\x13\x06\x53\x79\x64\x6E\x65\x79\x31\x14\x30\x12\x06\x03\x55\x04\x0A\x13\x0B\x43\x41\x63\x65\x72\x74\x20\x49\x6E\x63\x2E\x31\x1E\x30\x1C\x06\x03\x55\x04\x0B\x13\x15\x53\x65\x72\x76\x65\x72\x20\x41\x64\x6D\x69\x6E\x69\x73\x74\x72\x61\x74\x69\x6F\x6E\x31\x18\x30\x16\x06\x03\x55\x04\x03\x13\x0F\x6F\x63\x73\x70\x2E\x63\x61\x63\x65\x72\x74\x2E\x6F\x72\x67\x18\x0F\x32\x30\x31\x32\x30\x31\x31\x33\x30\x38\x35\x30\x34\x32\x5A\x30\x66\x30\x64\x30\x3C\x30\x09\x06\x05\x2B\x0E\x03\x02\x1A\x05\x00\x04\x14\xF2\x2A\x62\x16\x93\xA6\xDA\x5A\xD0\xB9\x8D\x3A\x13\x5E\x35\xD1\xEB\x18\x36\x61\x04\x14\x75\xA8\x71\x60\x4C\x88\x13\xF0\x78\xD9\x89\x77\xB5\x6D\xC5\x89\xDF\xBC\xB1\x7A\x02\x03\x00\xBC\xE0\x80\x00\x18\x0F\x32\x30\x31\x32\x30\x31\x31\x33\x30\x37\x32\x30\x34\x39\x5A\xA0\x11\x18\x0F\x32\x30\x31\x32\x30\x31\x31\x35\x30\x38\x35\x30\x34\x32\x5A\xA1\x2A\x30\x28\x30\x26\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x02\x04\x19\x04\x17\x73\x69\xD2\xC5\x6F\xC7\x7E\x2E\xB0\x2F\xCC\xC3\xE2\x80\xD6\x2A\xCE\xD3\xDE\x8F\x27\x1B\xB2\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x03\x82\x01\x01\x00\x3E\x50\x9D\xE9\xA2\xE0\xCA\x33\x88\x9B\x28\x7E\xE7\xA4\xAF\xDA\xBB\x75\x2D\xD9\x66\xA6\xD5\xFA\x17\x56\xC0\x3B\xDD\x74\xB6\x7E\x42\x2C\x28\xD0\x73\x91\x54\x69\xFA\xCF\xD8\xC7\x74\x1C\x5D\xBC\x8E\xCD\xE3\x0E\xD5\x3F\x80\x71\x9C\x95\x53\xC4\xD1\x95\x63\x5D\x72\xCE\xCC\x77\x9D\x7C\xAD\x47\x3F\x34\xDA\x90\x80\xC5\x15\xE1\x2B\xEE\x98\x57\xA3\xA7\x9F\xA2\xC3\xF5\x5E\xF7\x13\x26\x52\xDA\x09\x38\x5B\x18\x91\x07\x38\xCF\x09\xDA\x08\xED\x80\x4F\x26\x3A\xB9\xBE\xF6\xED\x65\x3F\xB1\x3A\x6D\xA3\x87\x22\xA3\x2A\xA5\x99\xCC\x06\xF3\x5A\xD5\x34\xFB\x9E\x32\x28\xC3\x3E\xF4\xAF\x33\x02\xCF\x6A\x74\x73\x17\x24\x17\x41\x0D\x7E\x86\x79\x83\x34\xE8\x82\x0A\x0D\x21\xED\xCB\x3B\xB7\x31\x64\xC9\xB6\x1E\xC7\x0C\x75\xCE\xBA\xB7\xDC\xB2\x67\x96\x2B\xAD\xBF\x86\x22\x81\x54\x66\xBA\x68\x89\xD7\x7E\x35\x60\x93\xEC\x6B\xD8\x59\x23\xA0\xD0\x95\x55\x8F\x93\x52\x48\x4E\x48\xCB\x92\xE9\x67\x71\x60\x07\xC9\xA3\x3B\xAC\xD1\xEA\x5B\x71\xDB\xC1\x94\x79\x85\x55\x8C\x03\x61\x9E\xC7\xD6\x32\x40\xFA\xDD\xF6\xC9\xF8\xE0\xFF\x4D\xAC\x54\xED\x61\xFE\xB2\xA0\x82\x04\x99\x30\x82\x04\x95\x30\x82\x04\x91\x30\x82\x02\x79\xA0\x03\x02\x01\x02\x02\x03\x00\xDC\xA6\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x30\x54\x31\x14\x30\x12\x06\x03\x55\x04\x0A\x13\x0B\x43\x41\x63\x65\x72\x74\x20\x49\x6E\x63\x2E\x31\x1E\x30\x1C\x06\x03\x55\x04\x0B\x13\x15\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x43\x41\x63\x65\x72\x74\x2E\x6F\x72\x67\x31\x1C\x30\x1A\x06\x03\x55\x04\x03\x13\x13\x43\x41\x63\x65\x72\x74\x20\x43\x6C\x61\x73\x73\x20\x33\x20\x52\x6F\x6F\x74\x30\x1E\x17\x0D\x31\x31\x30\x38\x32\x33\x30\x30\x30\x38\x33\x37\x5A\x17\x0D\x31\x33\x30\x38\x32\x32\x30\x30\x30\x38\x33\x37\x5A\x30\x7C\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x41\x55\x31\x0C\x30\x0A\x06\x03\x55\x04\x08\x13\x03\x4E\x53\x57\x31\x0F\x30\x0D\x06\x03\x55\x04\x07\x13\x06\x53\x79\x64\x6E\x65\x79\x31\x14\x30\x12\x06\x03\x55\x04\x0A\x13\x0B\x43\x41\x63\x65\x72\x74\x20\x49\x6E\x63\x2E\x31\x1E\x30\x1C\x06\x03\x55\x04\x0B\x13\x15\x53\x65\x72\x76\x65\x72\x20\x41\x64\x6D\x69\x6E\x69\x73\x74\x72\x61\x74\x69\x6F\x6E\x31\x18\x30\x16\x06\x03\x55\x04\x03\x13\x0F\x6F\x63\x73\x70\x2E\x63\x61\x63\x65\x72\x74\x2E\x6F\x72\x67\x30\x82\x01\x22\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x82\x01\x0F\x00\x30\x82\x01\x0A\x02\x82\x01\x01\x00\x9C\xC6\xD4\x6F\xE4\x23\xC7\xC3\x70\x4B\x75\x1F\xE4\xFC\xAE\xF6\x62\xC4\x60\xA1\xD6\xCF\xF9\x47\x40\x38\xD9\xAF\x06\xF5\xB3\x87\x09\xBA\x07\xC8\x7A\x3B\xE3\x3A\xE2\xC1\x6B\xDB\x0E\x9B\x7B\xB4\x98\x04\x40\x88\xC8\xE4\x20\x34\x9D\x5F\x94\xAE\x0C\xA0\x05\xA1\x74\x10\x3F\x1F\x93\x6D\xC5\xA0\xCE\x29\xB0\x2A\x03\x6E\xED\x3B\xD1\x9A\x7A\xF7\x0F\xA7\xB7\x39\xD7\xC3\xB4\xDE\x15\x67\x94\xF2\xEF\xB0\xDD\x5F\xE3\xC9\xD8\xD2\x34\x0E\x5D\x44\xDF\xBF\x99\xD8\x5E\x60\xF4\x39\x24\x8A\xFD\x5D\xC8\x46\x8D\x0A\xB1\x60\x7A\x4F\xD5\x27\x30\x60\x9E\x13\x06\xF8\x3A\xAA\xB3\xBB\x33\x34\x6F\x84\x81\x7E\x5C\xCC\x12\x89\xF2\xFE\x6E\x93\x83\xFA\x8B\xEE\xAB\x36\x4C\xB6\x40\xA9\xEE\xFB\xF8\x16\x5A\x55\xD1\x64\x0D\x49\xDA\x04\xDE\xD1\xC8\xCA\xEE\x5F\x24\xB1\x79\x78\xB3\x9A\x88\x13\xDD\x68\x51\x39\xE9\x68\x31\xAF\xD7\xF8\x4D\x35\x6D\x60\x58\x04\x42\xBB\x55\x92\x18\xF6\x98\x01\xA5\x74\x3B\xBC\x36\xDB\x20\x68\x18\xB8\x85\xD4\x8B\x6D\x30\x87\x4D\xD6\x33\x2D\x7A\x54\x36\x1D\x57\x42\x14\x5C\x7A\x62\x74\xD5\x1E\x2B\xD5\xBF\x04\xF3\xFF\xEC\x03\xC1\x02\x03\x01\x00\x01\xA3\x44\x30\x42\x30\x0C\x06\x03\x55\x1D\x13\x01\x01\xFF\x04\x02\x30\x00\x30\x27\x06\x03\x55\x1D\x25\x04\x20\x30\x1E\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x02\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x01\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x09\x30\x09\x06\x03\x55\x1D\x11\x04\x02\x30\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x03\x82\x02\x01\x00\x50\xDD\x63\xB7\x1A\x6F\x91\x4C\xE8\x7F\x82\x1A\x27\x04\x81\x05\xBB\xA6\x69\xAC\x41\x7B\x62\xFC\x4B\x08\xDC\x60\xCF\xB2\x5A\xF1\xB4\xB5\x27\x69\x6B\x12\xE4\x07\xC8\x16\xCE\x3B\x42\xCC\x02\x90\x66\x0E\x79\xB8\x6C\x4B\x90\x00\xC5\x66\x64\x92\x2B\x2B\x48\x0E\x84\xC2\x6D\xBF\xA5\xDE\x16\xE3\xBD\x19\xF5\x5C\x93\xA1\x86\x7F\xD9\x89\x78\x6A\x3F\x83\xF0\xAA\xF8\xEA\x1D\xA4\x13\xF7\x2A\x15\x4C\x51\x9C\xC4\xB0\xBE\x58\x66\xCF\x4C\x6C\x3D\x31\xE5\xF9\x54\x21\xCD\xA1\x30\x01\x6A\xB3\x1A\x48\x85\x34\x93\xB8\xF9\x15\x19\x48\x34\x8D\x73\xE7\x03\x50\xAF\xDE\x50\xC7\x62\xAF\x25\x22\x2B\xF6\xE8\x37\x2E\xE4\x71\xA9\x5C\x26\xEA\x79\xCB\x04\x29\x73\x6B\x8F\xDF\x1F\x5C\x41\x52\xC0\x36\xAA\xD7\x7D\x8E\x44\x54\x98\x06\x4C\x63\xA6\x0B\x01\x94\x5D\x0C\x5C\xD4\xCF\xCB\x0B\x7B\x2D\x56\xCC\xBF\x97\x7F\x15\x24\x1D\xBA\xEA\xB7\x97\xB0\x32\xAD\xFC\xEA\x6D\x94\x39\x7A\xE3\x25\x54\xFC\x4A\xF5\x3D\xBD\x2E\xD5\x31\x07\x49\x24\xCC\x92\x69\x0E\x79\xB9\xDF\xDB\x36\xBF\x04\x44\x15\xD0\x46\x99\x8C\xD2\x4C\x94\x38\x0E\x10\x64\x13\xAB\xD9\x1B\x54\x02\x31\x56\x20\xEE\x69\x95\xDF\x39\xBB\xE9\xA7\x6D\xC3\x23\x86\x0B\xD6\x34\x40\x37\xC3\xD4\x41\xA8\x2E\x71\x1D\x6E\x5B\xD7\xC5\x9F\x2A\xE6\x02\x80\xAE\x0A\x28\x69\x63\x4B\x89\x2E\xBD\x4F\x42\x58\xFB\x86\x9A\xA2\x18\xDC\xC6\x32\xC1\x46\xBA\x28\xD2\x8B\xCE\x56\x63\x04\x80\x51\x51\x39\x00\x3B\x00\xB9\x5F\x67\xFA\x90\x1E\xDA\x76\xB5\x31\xA5\xBD\x11\xD2\x5F\xDA\x5D\xD5\xF7\xEE\xAB\xC0\x62\x74\x60\x47\x32\x42\xFD\xB2\x2E\x04\x3A\x2E\xF2\xC8\xB3\x41\xA3\xBD\xFE\x94\x5F\xEF\x6E\xD7\x92\x7C\x1D\x04\xF0\xC6\x53\x8E\x46\xDC\x30\x3A\x35\x5F\x1A\x4B\xEA\x3B\x00\x8B\x97\xB5\xB9\xCE\x71\x6E\x5C\xD5\xA0\x0B\xB1\x33\x08\x89\x61\x23\xCF\x97\x9F\x8F\x9A\x50\xB5\xEC\xCE\x40\x8D\x82\x95\x8B\x79\x26\x66\xF3\xF4\x70\xD8\xEE\x58\xDD\x75\x29\xD5\x6A\x91\x51\x7A\x17\xBC\x4F\xD4\xA3\x45\x7B\x84\xE7\xBE\x69\x53\xC1\xE2\x5C\xC8\x45\xA0\x3A\xEC\xDF\x8A\x1E\xC1\x18\x84\x8B\x7A\x4E\x4E\x9E\x3A\x26\xFE\x5D\x22\xD4\xC5\x14\xBE\xEE\x06\xEB\x05\x4A\x66\xC9\xA4\xB3\x68\x04\xB0\x5D\x25\x54\xB3\x05\xED\x41\xF0\x65\x69\x6D\xA5\x4E\xB7\x97\xD8\xD8\xF5"
+
+static const gnutls_datum_t blog_resp =
+  { (unsigned char*) BLOG_RESP, sizeof (BLOG_RESP) - 1 };
+
+static unsigned char blog_cert_pem[] =
+  "-----BEGIN CERTIFICATE-----\n"
+  "MIIE8DCCAtigAwIBAgIDALzgMA0GCSqGSIb3DQEBBQUAMFQxFDASBgNVBAoTC0NB\n"
+  "Y2VydCBJbmMuMR4wHAYDVQQLExVodHRwOi8vd3d3LkNBY2VydC5vcmcxHDAaBgNV\n"
+  "BAMTE0NBY2VydCBDbGFzcyAzIFJvb3QwHhcNMTAxMTE2MjI1MjMzWhcNMTIxMTE1\n"
+  "MjI1MjMzWjAdMRswGQYDVQQDExJibG9nLmpvc2Vmc3Nvbi5vcmcwggEiMA0GCSqG\n"
+  "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBKA6bm/Kip0i00vU+BOmUF2MBDTwps41c\n"
+  "xKN5bDn7usWZj8loi6BHRPE2WzCVPnPRD1FJXBc4rXL8zZWrCRe1b4A+l8NjPN2o\n"
+  "uUgJvYLXYQ2hXkvxlPBQPKNOudaOAVsahpyxk6g6Z3mskOfqPhxvjutHvMC4fOsJ\n"
+  "1+FstMzvg5SpDd4uYM9m0UK8pbEUSuwW+fxyWqhciSi7kJtdrD6bwx3ub3t9GFkM\n"
+  "9uTzImIslTq19w8AHQsTICNnmNwfUGF5XMUIuxun0HlFt2KUP5G3Qg9Cd18wZFql\n"
+  "RQJvLA3nbVFtmN3M3yKXnGSsEn38ZJvC+UxFuSfYJN9UwgoG6gwhAgMBAAGjggEA\n"
+  "MIH9MAwGA1UdEwEB/wQCMAAwNAYDVR0lBC0wKwYIKwYBBQUHAwIGCCsGAQUFBwMB\n"
+  "BglghkgBhvhCBAEGCisGAQQBgjcKAwMwCwYDVR0PBAQDAgWgMDMGCCsGAQUFBwEB\n"
+  "BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuY2FjZXJ0Lm9yZy8wdQYDVR0R\n"
+  "BG4wbIISYmxvZy5qb3NlZnNzb24ub3JnoCAGCCsGAQUFBwgFoBQMEmJsb2cuam9z\n"
+  "ZWZzc29uLm9yZ4ISYmxvZy5qb3NlZnNzb24ub3JnoCAGCCsGAQUFBwgFoBQMEmJs\n"
+  "b2cuam9zZWZzc29uLm9yZzANBgkqhkiG9w0BAQUFAAOCAgEACQX0KziT81G0XJ4C\n"
+  "SlVumGN0KcVPDjtiUYskMpUvyLF951Q4Uuih0Aa9c0LynyZq8yqr6sW5OTmnRfSU\n"
+  "DuUK5IH+IPq5PU7qteQSIy+63yjMQ+1wye1zfCWI+MyaS54AOn6uZObsr4grq41i\n"
+  "sTwnX8OF/z15dQBjDR18WoehsnbuMz3Ld7+w5UcVWRGDzTyZ7JrYisEywQ7TXcoK\n"
+  "1IlhD1TqwFucH7lIr4mPWNjL7Nw0sw11HN0Syt9H3upcq6lqyEI0ygfNZ9cdxvmX\n"
+  "WqOBxxLc6G/87G4nGW4jw3WrCX7LqSmChlR3SbEC1UhWpaQMQ+mOU5+vXon7blRV\n"
+  "zGJ/1wK8mKu3fKw9rm5TQ1xfJuRABbzsD3BrrUaHlREQQ+i6SCPVFGer6oeAaxyv\n"
+  "so0NCbmBQkcpmUUl0COIR/Lh/YT78PjIEfxaUnUlaZXvCbKPKP2cM8LY7ltEaTgJ\n"
+  "4W6sZi3QNFySzd4sz7J/YhY/jGjqku7TfpN/GOheW8AzKTBlm3WLps1YXys4TKrB\n"
+  "0RStfaPfRJI1PeSlrWl6+kQu/5O8WA8NK0JZ/0Jc4d5LNrtUXo4VU9XCthrxLkgL\n"
+  "3XWgZKFrqJd1UeJJ7OvkRYfI1c5i4oAP5ksuF0SHTpqnXE8K39kUnUx3B+ItJlZP\n"
+  "VXTFhXRc06QwYqYXuYSAmj7/GJk=\n"
+  "-----END CERTIFICATE-----\n";
+const gnutls_datum_t blog_cert_data = { blog_cert_pem,
+                                       sizeof (blog_cert_pem) };
+
+static unsigned char blog_issuer_pem[] =
+  "-----BEGIN CERTIFICATE-----\n"
+  "MIIHWTCCBUGgAwIBAgIDCkGKMA0GCSqGSIb3DQEBCwUAMHkxEDAOBgNVBAoTB1Jv\n"
+  "b3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZ\n"
+  "Q0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9y\n"
+  "dEBjYWNlcnQub3JnMB4XDTExMDUyMzE3NDgwMloXDTIxMDUyMDE3NDgwMlowVDEU\n"
+  "MBIGA1UEChMLQ0FjZXJ0IEluYy4xHjAcBgNVBAsTFWh0dHA6Ly93d3cuQ0FjZXJ0\n"
+  "Lm9yZzEcMBoGA1UEAxMTQ0FjZXJ0IENsYXNzIDMgUm9vdDCCAiIwDQYJKoZIhvcN\n"
+  "AQEBBQADggIPADCCAgoCggIBAKtJNRFIfNImflOUz0Op3SjXQiqL84d4GVh8D57a\n"
+  "iX3h++tykA10oZZkq5+gJJlz2uJVdscXe/UErEa4w75/ZI0QbCTzYZzA8pD6Ueb1\n"
+  "aQFjww9W4kpCz+JEjCUoqMV5CX1GuYrz6fM0KQhF5Byfy5QEHIGoFLOYZcRD7E6C\n"
+  "jQnRvapbjZLQ7N6QxX8KwuPr5jFaXnQ+lzNZ6MMDPWAzv/fRb0fEze5ig1JuLgia\n"
+  "pNkVGJGmhZJHsK5I6223IeyFGmhyNav/8BBdwPSUp2rVO5J+TJAFfpPBLIukjmJ0\n"
+  "FXFuC3ED6q8VOJrU0gVyb4z5K+taciX5OUbjchs+BMNkJyIQKopPWKcDrb60LhPt\n"
+  "XapI19V91Cp7XPpGBFDkzA5CW4zt2/LP/JaT4NsRNlRiNDiPDGCbO5dWOK3z0luL\n"
+  "oFvqTpa4fNfVoIZwQNORKbeiPK31jLvPGpKK5DR7wNhsX+kKwsOnIJpa3yxdUly6\n"
+  "R9Wb7yQocDggL9V/KcCyQQNokszgnMyXS0XvOhAKq3A6mJVwrTWx6oUrpByAITGp\n"
+  "rmB6gCZIALgBwJNjVSKRPFbnr9s6JfOPMVTqJouBWfmh0VMRxXudA/Z0EeBtsSw/\n"
+  "LIaRmXGapneLNGDRFLQsrJ2vjBDTn8Rq+G8T/HNZ92ZCdB6K4/jc0m+YnMtHmJVA\n"
+  "BfvpAgMBAAGjggINMIICCTAdBgNVHQ4EFgQUdahxYEyIE/B42Yl3tW3Fid+8sXow\n"
+  "gaMGA1UdIwSBmzCBmIAUFrUyG9TH8+DmjvO90rA67rI5GNGhfaR7MHkxEDAOBgNV\n"
+  "BAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAG\n"
+  "A1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYS\n"
+  "c3VwcG9ydEBjYWNlcnQub3JnggEAMA8GA1UdEwEB/wQFMAMBAf8wXQYIKwYBBQUH\n"
+  "AQEEUTBPMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5DQWNlcnQub3JnLzAoBggr\n"
+  "BgEFBQcwAoYcaHR0cDovL3d3dy5DQWNlcnQub3JnL2NhLmNydDBKBgNVHSAEQzBB\n"
+  "MD8GCCsGAQQBgZBKMDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuQ0FjZXJ0Lm9y\n"
+  "Zy9pbmRleC5waHA/aWQ9MTAwNAYJYIZIAYb4QgEIBCcWJWh0dHA6Ly93d3cuQ0Fj\n"
+  "ZXJ0Lm9yZy9pbmRleC5waHA/aWQ9MTAwUAYJYIZIAYb4QgENBEMWQVRvIGdldCB5\n"
+  "b3VyIG93biBjZXJ0aWZpY2F0ZSBmb3IgRlJFRSwgZ28gdG8gaHR0cDovL3d3dy5D\n"
+  "QWNlcnQub3JnMA0GCSqGSIb3DQEBCwUAA4ICAQApKIWuRKm5r6R5E/CooyuXYPNc\n"
+  "7uMvwfbiZqARrjY3OnYVBFPqQvX56sAV2KaC2eRhrnILKVyQQ+hBsuF32wITRHhH\n"
+  "Va9Y/MyY9kW50SD42CEH/m2qc9SzxgfpCYXMO/K2viwcJdVxjDm1Luq+GIG6sJO4\n"
+  "D+Pm1yaMMVpyA4RS5qb1MyJFCsgLDYq4Nm+QCaGrvdfVTi5xotSu+qdUK+s1jVq3\n"
+  "VIgv7nSf7UgWyg1I0JTTrKSi9iTfkuO960NAkW4cGI5WtIIS86mTn9S8nK2cde5a\n"
+  "lxuV53QtHA+wLJef+6kzOXrnAzqSjiL2jA3k2X4Ndhj3AfnvlpaiVXPAPHG0HRpW\n"
+  "Q7fDCo1y/OIQCQtBzoyUoPkD/XFzS4pXM+WOdH4VAQDmzEoc53+VGS3FpQyLu7Xt\n"
+  "hbNc09+4ufLKxw0BFKxwWMWMjTPUnWajGlCVI/xI4AZDEtnNp4Y5LzZyo4AQ5OHz\n"
+  "0ctbGsDkgJp8E3MGT9ujayQKurMcvEp4u+XjdTilSKeiHq921F73OIZWWonO1sOn\n"
+  "ebJSoMbxhbQljPI/lrMQ2Y1sVzufb4Y6GIIiNsiwkTjbKqGTqoQ/9SdlrnPVyNXT\n"
+  "d+pLncdBu8fA46A/5H2kjXPmEkvfoXNzczqA6NXLji/L6hOn1kGLrPo8idck9U60\n"
+  "4GGSt/M3mMS+lqO3ig==\n"
+  "-----END CERTIFICATE-----\n";
+const gnutls_datum_t blog_issuer_data = { blog_issuer_pem,
+                                         sizeof (blog_issuer_pem) };
+
+static unsigned char blog_signer_pem[] =
+  "-----BEGIN CERTIFICATE-----\n"
+  "MIIEkTCCAnmgAwIBAgIDANymMA0GCSqGSIb3DQEBBQUAMFQxFDASBgNVBAoTC0NB\n"
+  "Y2VydCBJbmMuMR4wHAYDVQQLExVodHRwOi8vd3d3LkNBY2VydC5vcmcxHDAaBgNV\n"
+  "BAMTE0NBY2VydCBDbGFzcyAzIFJvb3QwHhcNMTEwODIzMDAwODM3WhcNMTMwODIy\n"
+  "MDAwODM3WjB8MQswCQYDVQQGEwJBVTEMMAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZT\n"
+  "eWRuZXkxFDASBgNVBAoTC0NBY2VydCBJbmMuMR4wHAYDVQQLExVTZXJ2ZXIgQWRt\n"
+  "aW5pc3RyYXRpb24xGDAWBgNVBAMTD29jc3AuY2FjZXJ0Lm9yZzCCASIwDQYJKoZI\n"
+  "hvcNAQEBBQADggEPADCCAQoCggEBAJzG1G/kI8fDcEt1H+T8rvZixGCh1s/5R0A4\n"
+  "2a8G9bOHCboHyHo74zriwWvbDpt7tJgEQIjI5CA0nV+UrgygBaF0ED8fk23FoM4p\n"
+  "sCoDbu070Zp69w+ntznXw7TeFWeU8u+w3V/jydjSNA5dRN+/mdheYPQ5JIr9XchG\n"
+  "jQqxYHpP1ScwYJ4TBvg6qrO7MzRvhIF+XMwSifL+bpOD+ovuqzZMtkCp7vv4FlpV\n"
+  "0WQNSdoE3tHIyu5fJLF5eLOaiBPdaFE56Wgxr9f4TTVtYFgEQrtVkhj2mAGldDu8\n"
+  "NtsgaBi4hdSLbTCHTdYzLXpUNh1XQhRcemJ01R4r1b8E8//sA8ECAwEAAaNEMEIw\n"
+  "DAYDVR0TAQH/BAIwADAnBgNVHSUEIDAeBggrBgEFBQcDAgYIKwYBBQUHAwEGCCsG\n"
+  "AQUFBwMJMAkGA1UdEQQCMAAwDQYJKoZIhvcNAQEFBQADggIBAFDdY7cab5FM6H+C\n"
+  "GicEgQW7pmmsQXti/EsI3GDPslrxtLUnaWsS5AfIFs47QswCkGYOebhsS5AAxWZk\n"
+  "kisrSA6Ewm2/pd4W470Z9VyToYZ/2Yl4aj+D8Kr46h2kE/cqFUxRnMSwvlhmz0xs\n"
+  "PTHl+VQhzaEwAWqzGkiFNJO4+RUZSDSNc+cDUK/eUMdiryUiK/boNy7kcalcJup5\n"
+  "ywQpc2uP3x9cQVLANqrXfY5EVJgGTGOmCwGUXQxc1M/LC3stVsy/l38VJB266reX\n"
+  "sDKt/OptlDl64yVU/Er1Pb0u1TEHSSTMkmkOebnf2za/BEQV0EaZjNJMlDgOEGQT\n"
+  "q9kbVAIxViDuaZXfObvpp23DI4YL1jRAN8PUQagucR1uW9fFnyrmAoCuCihpY0uJ\n"
+  "Lr1PQlj7hpqiGNzGMsFGuijSi85WYwSAUVE5ADsAuV9n+pAe2na1MaW9EdJf2l3V\n"
+  "9+6rwGJ0YEcyQv2yLgQ6LvLIs0Gjvf6UX+9u15J8HQTwxlOORtwwOjVfGkvqOwCL\n"
+  "l7W5znFuXNWgC7EzCIlhI8+Xn4+aULXszkCNgpWLeSZm8/Rw2O5Y3XUp1WqRUXoX\n"
+  "vE/Uo0V7hOe+aVPB4lzIRaA67N+KHsEYhIt6Tk6eOib+XSLUxRS+7gbrBUpmyaSz\n"
+  "aASwXSVUswXtQfBlaW2lTreX2Nj1\n"
+  "-----END CERTIFICATE-----\n";
+const gnutls_datum_t blog_signer_data = { blog_signer_pem,
+                                         sizeof (blog_signer_pem) };
+
+static void
+ocsp_invalid_calls (void)
+{
+  gnutls_ocsp_req_t req;
+  gnutls_ocsp_resp_t resp;
+  gnutls_datum_t dat;
+  char c = 42;
+  void *p = &c;
+  int rc;
+
+  rc = gnutls_ocsp_req_init (&req);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      fail ("gnutls_ocsp_req_init alloc\n");
+      exit (1);
+    }
+  rc = gnutls_ocsp_resp_init (&resp);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      fail ("gnutls_ocsp_resp_init alloc\n");
+      exit (1);
+    }
+
+  gnutls_ocsp_req_deinit (NULL);
+  gnutls_ocsp_resp_deinit (NULL);
+
+  rc = gnutls_ocsp_req_import (NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_import NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_import (NULL, p);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_import NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_import (req, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_import NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_import (NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_resp_import NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_import (NULL, p);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_resp_import NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_import (resp, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_resp_import NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_export (NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_export NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_export (NULL, p);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_export NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_export (req, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_export NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_export (NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_resp_export NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_export (NULL, p);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_resp_export NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_export (resp, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_resp_export NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_get_version (NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_get_version NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_get_cert_id (NULL, 0, NULL, NULL, NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_get_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_get_cert_id (req, 0, NULL, NULL, NULL, NULL);
+  if (rc != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+    {
+      fail ("gnutls_ocsp_req_get_cert_id empty\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_add_cert_id (NULL, 0, NULL, NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_add_cert_id (req, 0, NULL, NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_add_cert_id (req, GNUTLS_DIG_SHA1, NULL, NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_add_cert_id (req, GNUTLS_DIG_SHA1, p, NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_add_cert_id (req, GNUTLS_DIG_SHA1, NULL, p, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_add_cert_id (req, GNUTLS_DIG_SHA1, NULL, NULL, p);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_add_cert_id (req, GNUTLS_DIG_SHA1, p, p, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_add_cert_id (req, GNUTLS_DIG_SHA1, p, NULL, p);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_add_cert_id (req, GNUTLS_DIG_SHA1, NULL, p, p);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_add_cert (NULL, 0, NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_add_cert (req, 0, NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+
+  rc = gnutls_ocsp_req_add_cert (req, 0, p, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_add_cert (req, 0, NULL, p);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_add_cert_id NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_get_extension (NULL, 0, NULL, NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_get_extension NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_get_extension (req, 0, NULL, NULL, NULL);
+  if (rc != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+    {
+      fail ("gnutls_ocsp_req_get_extension NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_get_extension (req, 0, p, p, p);
+  if (rc != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+    {
+      fail ("gnutls_ocsp_req_get_extension NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_set_extension (NULL, NULL, 0, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_set_extension NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_set_extension (req, NULL, 0, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_set_extension NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_set_extension (req, p, 0, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_set_extension NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_set_extension (req, NULL, 0, p);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_set_extension NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_get_nonce (NULL, NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_get_nonce NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_get_nonce (NULL, NULL, p);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_get_nonce NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_set_nonce (NULL, 0, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_set_nonce NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_set_nonce (req, 0, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_set_nonce NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_req_randomize_nonce (NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_req_randomize_nonce NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_get_status (NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_resp_get_status NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_get_status (resp);
+  if (rc != GNUTLS_E_ASN1_VALUE_NOT_FOUND)
+    {
+      fail ("gnutls_ocsp_resp_get_status %d\n", rc);
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_get_response (NULL, NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_resp_get_response NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_get_response (NULL, p, p);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_resp_get_response NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_get_response (resp, NULL, NULL);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      fail ("gnutls_ocsp_resp_get_response %d\n", rc);
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_get_version (NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_resp_get_version NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_get_version (resp);
+  if (rc != 1)
+    {
+      fail ("gnutls_ocsp_resp_get_version ret %d\n", rc);
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_get_responder (NULL, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_resp_get_responder NULL\n");
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_get_responder (resp, NULL);
+  if (rc != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_ocsp_resp_get_responder 2nd %d\n", rc);
+      exit (1);
+    }
+
+  rc = gnutls_ocsp_resp_get_responder (resp, &dat);
+  if (rc != GNUTLS_E_SUCCESS || dat.size != 0)
+    {
+      fail ("gnutls_ocsp_resp_get_responder %d\n", rc);
+      exit (1);
+    }
+
+  gnutls_free (dat.data);
+
+  gnutls_ocsp_req_deinit (req);
+  gnutls_ocsp_resp_deinit (resp);
+}
+
+/* import a request, query some fields and print and export it */
+static void
+req_parse (void)
+{
+  gnutls_ocsp_req_t req;
+  int ret;
+  gnutls_datum_t d;
+
+  /* init request */
+
+  ret = gnutls_ocsp_req_init (&req);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_req_init\n");
+      exit (1);
+    }
+
+  /* import ocsp request */
+
+  ret = gnutls_ocsp_req_import (req, &req1);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_req_import %d\n", ret);
+      exit (1);
+    }
+
+  /* simple version query */
+
+  ret = gnutls_ocsp_req_get_version (req);
+  if (ret != 1)
+    {
+      fail ("gnutls_ocsp_req_get_version %d\n", ret);
+      exit (1);
+    }
+
+  /* check nonce */
+  {
+    gnutls_datum_t expect =
+      { (unsigned char*) REQ1NONCE + 2, sizeof (REQ1NONCE) - 3 };
+    gnutls_datum_t got;
+    unsigned int critical;
+
+    ret = gnutls_ocsp_req_get_nonce (req, &critical, &got);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_req_get_nonce %d\n", ret);
+       exit (1);
+      }
+
+    if (critical != 0)
+      {
+       fail ("unexpected critical %d\n", critical);
+       exit (1);
+      }
+
+    if (expect.size != got.size ||
+       memcmp (expect.data, got.data, got.size) != 0)
+      {
+       fail ("ocsp request nonce memcmp failed\n");
+       exit (1);
+      }
+
+    gnutls_free (got.data);
+  }
+
+  /* print request */
+
+  ret = gnutls_ocsp_req_print (req, GNUTLS_OCSP_PRINT_FULL, &d);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_req_print\n");
+      exit (1);
+    }
+
+  if (strlen (REQ1INFO) != d.size - 1 ||
+      memcmp (REQ1INFO, d.data, strlen (REQ1INFO)) != 0)
+    {
+      printf ("expected (len %ld):\n%s\ngot (len %d):\n%.*s\n",
+             strlen (REQ1INFO), REQ1INFO, (int) d.size - 1,
+             (int) d.size, d.data);
+      fail ("ocsp request print failed\n");
+      exit (1);
+    }
+  gnutls_free (d.data);
+
+  /* test export */
+  ret = gnutls_ocsp_req_export (req, &d);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_req_export %d\n", ret);
+      exit (1);
+    }
+
+  /* compare against earlier imported bytes */
+
+  if (req1.size != d.size ||
+      memcmp (req1.data, d.data, d.size) != 0)
+    {
+      fail ("ocsp request export memcmp failed\n");
+      exit (1);
+    }
+  gnutls_free (d.data);
+
+  /* test setting nonce */
+  {
+    gnutls_datum_t n1 = { (unsigned char *) "foo", 3 };
+    gnutls_datum_t n2 = { (unsigned char *) "foobar", 6 };
+    gnutls_datum_t got;
+    unsigned critical;
+
+    ret = gnutls_ocsp_req_set_nonce (req, 0, &n1);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_req_set_nonce %d\n", ret);
+       exit (1);
+      }
+
+    ret = gnutls_ocsp_req_get_nonce (req, &critical, &got);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_req_get_nonce %d\n", ret);
+       exit (1);
+      }
+
+    if (critical != 0)
+      {
+       fail ("unexpected critical %d\n", critical);
+       exit (1);
+      }
+
+    if (n1.size != got.size ||
+       memcmp (n1.data, got.data, got.size) != 0)
+      {
+       fail ("ocsp request parse nonce memcmp failed\n");
+       exit (1);
+      }
+
+    gnutls_free (got.data);
+
+    /* set another time */
+
+    ret = gnutls_ocsp_req_set_nonce (req, 1, &n2);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_req_set_nonce %d\n", ret);
+       exit (1);
+      }
+
+    ret = gnutls_ocsp_req_get_nonce (req, &critical, &got);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_req_get_nonce %d\n", ret);
+       exit (1);
+      }
+
+    if (critical != 1)
+      {
+       fail ("unexpected critical %d\n", critical);
+       exit (1);
+      }
+
+    if (n2.size != got.size ||
+       memcmp (n2.data, got.data, got.size) != 0)
+      {
+       fail ("ocsp request parse2 nonce memcmp failed\n");
+       exit (1);
+      }
+
+    gnutls_free (got.data);
+
+    /* randomize nonce */
+
+    ret = gnutls_ocsp_req_randomize_nonce (req);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_req_randomize_nonce %d\n", ret);
+       exit (1);
+      }
+
+    ret = gnutls_ocsp_req_get_nonce (req, &critical, &n1);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_req_get_nonce %d\n", ret);
+       exit (1);
+      }
+
+    if (critical != 0)
+      {
+       fail ("unexpected random critical %d\n", critical);
+       exit (1);
+      }
+
+    ret = gnutls_ocsp_req_randomize_nonce (req);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_req_randomize_nonce %d\n", ret);
+       exit (1);
+      }
+
+    ret = gnutls_ocsp_req_get_nonce (req, &critical, &n2);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_req_get_nonce %d\n", ret);
+       exit (1);
+      }
+
+    if (critical != 0)
+      {
+       fail ("unexpected random critical %d\n", critical);
+       exit (1);
+      }
+
+    if (n2.size == got.size && memcmp (n1.data, n2.data, n1.size) == 0)
+      {
+       fail ("ocsp request random nonce memcmp failed\n");
+       exit (1);
+      }
+
+    gnutls_free (n1.data);
+    gnutls_free (n2.data);
+  }
+
+  /* cleanup */
+
+  gnutls_ocsp_req_deinit (req);
+}
+
+/* check that creating a request (using low-level add_cert_id) ends up
+   with same DER as above. */
+static void
+req_addcert_id (void)
+{
+  gnutls_ocsp_req_t req;
+  int ret;
+  gnutls_datum_t d;
+
+  /* init request */
+
+  ret = gnutls_ocsp_req_init (&req);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_req_init\n");
+      exit (1);
+    }
+
+  /* add ocsp request nonce */
+
+  {
+    gnutls_datum_t nonce =
+      { (unsigned char*) REQ1NONCE, sizeof (REQ1NONCE) - 1 };
+
+    ret = gnutls_ocsp_req_set_extension (req, "1.3.6.1.5.5.7.48.1.2",
+                                        0, &nonce);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_req_set_extension %d\n", ret);
+       exit (1);
+      }
+  }
+
+  /* add cert_id */
+  {
+    gnutls_datum_t issuer_name_hash =
+      { (unsigned char*) REQ1INH, sizeof (REQ1INH) - 1 };
+    gnutls_datum_t issuer_key_hash =
+      { (unsigned char*) REQ1IKH, sizeof (REQ1IKH) - 1 };
+    gnutls_datum_t serial_number =
+      { (unsigned char*) REQ1SN, sizeof (REQ1SN) - 1 };
+
+    ret = gnutls_ocsp_req_add_cert_id (req, GNUTLS_DIG_SHA1,
+                                     &issuer_name_hash,
+                                     &issuer_key_hash,
+                                     &serial_number);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_add_cert_id %d\n", ret);
+       exit (1);
+      }
+  }
+
+  /* print request */
+
+  ret = gnutls_ocsp_req_print (req, GNUTLS_OCSP_PRINT_FULL, &d);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_req_print\n");
+      exit (1);
+    }
+
+  if (strlen (REQ1INFO) != d.size - 1 ||
+      memcmp (REQ1INFO, d.data, strlen (REQ1INFO)) != 0)
+    {
+      printf ("expected (len %ld):\n%s\ngot (len %d):\n%.*s\n",
+             strlen (REQ1INFO), REQ1INFO, (int) d.size - 1,
+             (int) d.size, d.data);
+      fail ("ocsp request print failed\n");
+      exit (1);
+    }
+  gnutls_free (d.data);
+
+  /* test export */
+  ret = gnutls_ocsp_req_export (req, &d);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_req_export %d\n", ret);
+      exit (1);
+    }
+
+  /* compare against earlier imported bytes */
+
+  if (req1.size != d.size ||
+      memcmp (req1.data, d.data, d.size) != 0)
+    {
+      fail ("ocsp request export memcmp failed\n");
+      exit (1);
+    }
+  gnutls_free (d.data);
+
+  /* cleanup */
+
+  gnutls_ocsp_req_deinit (req);
+}
+
+/* check that creating a request (using high-level add_cert) ends up
+   with same DER as above. */
+static void
+req_addcert (void)
+{
+  gnutls_ocsp_req_t req;
+  int ret;
+  gnutls_datum_t d;
+
+  /* init request */
+
+  ret = gnutls_ocsp_req_init (&req);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_req_init\n");
+      exit (1);
+    }
+
+  /* add ocsp request nonce */
+
+  {
+    gnutls_datum_t nonce =
+      { (unsigned char*) REQ1NONCE, sizeof (REQ1NONCE) - 1 };
+
+    ret = gnutls_ocsp_req_set_extension (req, "1.3.6.1.5.5.7.48.1.2",
+                                        0, &nonce);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_req_set_extension %d\n", ret);
+       exit (1);
+      }
+  }
+
+  /* add cert_id */
+  {
+    gnutls_x509_crt_t issuer = NULL, subject = NULL;
+
+    ret = gnutls_x509_crt_init (&issuer);
+    if (ret < 0)
+      {
+       fail ("gnutls_x509_crt_init (issuer) %d\n", ret);
+       exit (1);
+      }
+
+    ret = gnutls_x509_crt_init (&subject);
+    if (ret < 0)
+      {
+       fail ("gnutls_x509_crt_init (subject) %d\n", ret);
+       exit (1);
+      }
+
+    ret = gnutls_x509_crt_import (issuer, &issuer_data, GNUTLS_X509_FMT_PEM);
+    if (ret < 0)
+      {
+       fail ("gnutls_x509_crt_import (issuer) %d\n", ret);
+       exit (1);
+      }
+
+    ret = gnutls_x509_crt_import (subject, &subject_data, GNUTLS_X509_FMT_PEM);
+    if (ret < 0)
+      {
+       fail ("gnutls_x509_crt_import (subject) %d\n", ret);
+       exit (1);
+      }
+
+    ret = gnutls_ocsp_req_add_cert (req, GNUTLS_DIG_SHA1,
+                                   issuer, subject);
+    if (ret != 0)
+      {
+       fail ("gnutls_ocsp_add_cert %d\n", ret);
+       exit (1);
+      }
+
+    gnutls_x509_crt_deinit (subject);
+    gnutls_x509_crt_deinit (issuer);
+  }
+
+  /* print request */
+
+  ret = gnutls_ocsp_req_print (req, GNUTLS_OCSP_PRINT_FULL, &d);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_req_print\n");
+      exit (1);
+    }
+
+  if (strlen (REQ1INFO) != d.size - 1 ||
+      memcmp (REQ1INFO, d.data, strlen (REQ1INFO)) != 0)
+    {
+      printf ("expected (len %ld):\n%s\ngot (len %d):\n%.*s\n",
+             strlen (REQ1INFO), REQ1INFO, (int) d.size - 1,
+             (int) d.size, d.data);
+      fail ("ocsp request print failed\n");
+      exit (1);
+    }
+  gnutls_free (d.data);
+
+  /* test export */
+  ret = gnutls_ocsp_req_export (req, &d);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_req_export %d\n", ret);
+      exit (1);
+    }
+
+  /* compare against earlier imported bytes */
+
+  if (req1.size != d.size ||
+      memcmp (req1.data, d.data, d.size) != 0)
+    {
+      fail ("ocsp request export memcmp failed\n");
+      exit (1);
+    }
+  gnutls_free (d.data);
+
+  /* cleanup */
+
+  gnutls_ocsp_req_deinit (req);
+}
+
+static void
+resp_import (void)
+{
+  gnutls_ocsp_resp_t resp;
+  int ret;
+  gnutls_datum_t d;
+
+  /* init response */
+
+  ret = gnutls_ocsp_resp_init (&resp);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_resp_init\n");
+      exit (1);
+    }
+
+  /* import ocsp response */
+
+  ret = gnutls_ocsp_resp_import (resp, &resp1);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_resp_import %d\n", ret);
+      exit (1);
+    }
+
+  /* print response */
+
+  ret = gnutls_ocsp_resp_print (resp, GNUTLS_OCSP_PRINT_FULL, &d);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_resp_print\n");
+      exit (1);
+    }
+
+  if (strlen (RESP1INFO) != d.size - 1 ||
+      memcmp (RESP1INFO, d.data, strlen (RESP1INFO)) != 0)
+    {
+      printf ("expected (len %ld):\n%s\ngot (len %d):\n%.*s\n",
+             strlen (RESP1INFO), RESP1INFO, (int) d.size - 1,
+             (int) d.size, d.data);
+      fail ("ocsp response print failed\n");
+      exit (1);
+    }
+  gnutls_free (d.data);
+
+  /* import ocsp response */
+
+  ret = gnutls_ocsp_resp_import (resp, &resp2);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_resp_import %d\n", ret);
+      exit (1);
+    }
+
+  /* print response */
+
+  ret = gnutls_ocsp_resp_print (resp, GNUTLS_OCSP_PRINT_FULL, &d);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_resp_print\n");
+      exit (1);
+    }
+
+  if (memcmp (RESP2INFO, d.data, strlen (RESP2INFO)) != 0)
+    {
+      printf ("expected (len %ld):\n%s\ngot (len %d):\n%.*s\n",
+             strlen (RESP2INFO), RESP2INFO, (int) d.size - 1,
+             (int) d.size, d.data);
+      fail ("ocsp response print failed\n");
+      exit (1);
+    }
+  gnutls_free (d.data);
+
+  /* cleanup */
+
+  gnutls_ocsp_resp_deinit (resp);
+}
+
+static void
+resp_verify (void)
+{
+  gnutls_ocsp_resp_t resp;
+  int ret;
+  gnutls_x509_crt_t cert = NULL, issuer = NULL, signer = NULL;
+  gnutls_x509_trust_list_t list;
+  unsigned verify;
+
+  /* init response */
+
+  ret = gnutls_ocsp_resp_init (&resp);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_resp_init\n");
+      exit (1);
+    }
+
+  /* import ocsp response */
+
+  ret = gnutls_ocsp_resp_import (resp, &blog_resp);
+  if (ret != 0)
+    {
+      fail ("gnutls_ocsp_resp_import %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_x509_crt_init (&cert);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_init (cert) %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_x509_crt_init (&issuer);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_init (issuer) %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_x509_crt_init (&signer);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_init (signer) %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_x509_crt_import (cert, &blog_cert_data, GNUTLS_X509_FMT_PEM);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_import (cert) %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_x509_crt_import (issuer, &blog_issuer_data, 
GNUTLS_X509_FMT_PEM);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_import (issuer) %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_x509_crt_import (signer, &blog_signer_data, 
GNUTLS_X509_FMT_PEM);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_import (signer) %d\n", ret);
+      exit (1);
+    }
+
+  /* check direct verify with signer (should succeed) */
+
+  ret = gnutls_ocsp_resp_verify_direct (resp, signer, &verify, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_ocsp_resp_verify_direct (signer) %d\n", ret);
+      exit (1);
+    }
+
+  if (verify != 0)
+    {
+      fail ("gnutls_ocsp_resp_verify_direct %d\n", verify);
+      exit (1);
+    }
+
+  /* check direct verify with issuer (should fail) */
+
+  ret = gnutls_ocsp_resp_verify_direct (resp, issuer, &verify, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_ocsp_resp_verify_direct (issuer) %d\n", ret);
+      exit (1);
+    }
+
+  if (verify != GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
+    {
+      fail ("gnutls_ocsp_resp_verify_direct2 %d\n", verify);
+      exit (1);
+    }
+
+  /* check direct verify with cert (should fail) */
+
+  ret = gnutls_ocsp_resp_verify_direct (resp, cert, &verify, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_ocsp_resp_verify_direct (cert) %d\n", ret);
+      exit (1);
+    }
+
+  if (verify != GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
+    {
+      fail ("gnutls_ocsp_resp_verify_direct3 %d\n", verify);
+      exit (1);
+    }
+
+  /* check trust verify with issuer (should succeed) */
+
+  ret = gnutls_x509_trust_list_init (&list, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_trust_list_init %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_x509_trust_list_add_cas (list, &issuer, 1, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_trust_list_add_cas %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_ocsp_resp_verify (resp, list, &verify, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_ocsp_resp_verify (issuer) %d\n", ret);
+      exit (1);
+    }
+
+  if (verify != 0)
+    {
+      fail ("gnutls_ocsp_resp_verify %d\n", verify);
+      exit (1);
+    }
+
+  gnutls_x509_trust_list_deinit (list, 0);
+
+  /* check trust verify with signer (should succeed) */
+
+  ret = gnutls_x509_trust_list_init (&list, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_trust_list_init %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_x509_trust_list_add_cas (list, &signer, 1, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_trust_list_add_cas %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_ocsp_resp_verify (resp, list, &verify, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_ocsp_resp_verify (issuer) %d\n", ret);
+      exit (1);
+    }
+
+  if (verify != 0)
+    {
+      fail ("gnutls_ocsp_resp_verify %d\n", verify);
+      exit (1);
+    }
+
+  gnutls_x509_trust_list_deinit (list, 0);
+
+  /* check trust verify with cert (should fail) */
+
+  ret = gnutls_x509_trust_list_init (&list, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_trust_list_init %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_x509_trust_list_add_cas (list, &cert, 1, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_trust_list_add_cas %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_ocsp_resp_verify (resp, list, &verify, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_ocsp_resp_verify (issuer) %d\n", ret);
+      exit (1);
+    }
+
+  if (verify != GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER)
+    {
+      fail ("gnutls_ocsp_resp_verify %d\n", verify);
+      exit (1);
+    }
+
+  gnutls_x509_trust_list_deinit (list, 0);
+
+  /* check trust verify with all certs (should succeed) */
+
+  ret = gnutls_x509_trust_list_init (&list, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_trust_list_init %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_x509_trust_list_add_cas (list, &cert, 1, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_trust_list_add_cas %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_x509_trust_list_add_cas (list, &issuer, 1, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_trust_list_add_cas %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_x509_trust_list_add_cas (list, &signer, 1, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_trust_list_add_cas %d\n", ret);
+      exit (1);
+    }
+
+  ret = gnutls_ocsp_resp_verify (resp, list, &verify, 0);
+  if (ret < 0)
+    {
+      fail ("gnutls_ocsp_resp_verify (issuer) %d\n", ret);
+      exit (1);
+    }
+
+  if (verify != 0)
+    {
+      fail ("gnutls_ocsp_resp_verify %d\n", verify);
+      exit (1);
+    }
+
+  gnutls_x509_trust_list_deinit (list, 0);
+
+  /* cleanup */
+
+  gnutls_ocsp_resp_deinit (resp);
+  gnutls_x509_crt_deinit (cert);
+  gnutls_x509_crt_deinit (issuer);
+  gnutls_x509_crt_deinit (signer);
+}
+
+void
+doit (void)
+{
+  int ret;
+
+  ret = gnutls_global_init ();
+  if (ret < 0)
+    {
+      fail ("gnutls_global_init\n");
+      exit (1);
+    }
+
+  gnutls_global_set_log_function (tls_log_func);
+  gnutls_global_set_log_level (0);
+
+  ocsp_invalid_calls ();
+  req_parse ();
+  resp_import ();
+  req_addcert_id ();
+  req_addcert ();
+  resp_verify ();
+
+  /* we're done */
+
+  gnutls_global_deinit ();
+}


hooks/post-receive
-- 
GNU gnutls



reply via email to

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