[svn] ksba - r254 - in trunk: . src tests
svn author wk
cvs at cvs.gnupg.org
Thu Aug 31 17:47:50 CEST 2006
Author: wk
Date: 2006-08-31 17:47:49 +0200 (Thu, 31 Aug 2006)
New Revision: 254
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/README
trunk/TODO
trunk/configure.ac
trunk/src/ChangeLog
trunk/src/crl.c
trunk/src/ksba-config.in
trunk/src/ksba.h
trunk/src/ksba.m4
trunk/src/ocsp.c
trunk/src/ocsp.h
trunk/tests/ChangeLog
trunk/tests/t-common.h
trunk/tests/t-ocsp.c
Log:
Preparing the 1.0 release
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/ChangeLog 2006-08-31 15:47:49 UTC (rev 254)
@@ -1,3 +1,12 @@
+2006-08-31 Werner Koch <wk at g10code.com>
+
+ Released 1.0.0.
+
+ * configure.ac: Bumped LT version to C17/A9/R0.
+
+ * configure.ac: Require libgpg-error 1.2. Removed test on
+ GPG_ERR_UNKNOWN_CRIT_EXTN.
+
2006-08-01 Werner Koch <wk at g10code.com>
Released 0.9.16.
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/NEWS 2006-08-31 15:47:49 UTC (rev 254)
@@ -1,13 +1,19 @@
-Noteworthy changes in version 0.9.17
+Noteworthy changes in version 1.0.0 (2006-08-31)
-------------------------------------------------
* OCSP nonces are now checked to detect replay attacks.
* OCSP extensions may no be retrieved.
+ * Implemented ksba_ocsp_get_responder_id which used to always return
+ an error code not_implemented. Thus we can assume that the
+ function has never been used and we don't need to see this as an
+ API break.
+
* Interface changes relative to the 0.9.16 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ksba_ocsp_get_extension NEW
+ ksba_ocsp_get_responder_id CHANGED: No ABI break.
Noteworthy changes in version 0.9.16 (2006-08-01)
Modified: trunk/README
===================================================================
--- trunk/README 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/README 2006-08-31 15:47:49 UTC (rev 254)
@@ -1,7 +1,7 @@
LIBKSBA
---------
- Copyright 2001 g10 Code GmbH
+ Copyright 2001, 2006 g10 Code GmbH
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
@@ -41,8 +41,9 @@
A standard info format reference manual is included. However the OCSP
feature has not yet been documented. See the comments in src/ocsp.c
-and the example tests/t-ocsp.c. The program dirmngr uses the ocsp
-feature and may be used as another example.
+and the example tests/t-ocsp.c. The package dirmngr make extensive
+use of the ocsp feature and may be used as another example.
+
Modified: trunk/TODO
===================================================================
--- trunk/TODO 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/TODO 2006-08-31 15:47:49 UTC (rev 254)
@@ -51,4 +51,3 @@
** The ASN.1 parse tree is not released in all places
** Some memory is not released in case of errors.
-* Implement ksba_ocsp_get_extension!!!!
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/configure.ac 2006-08-31 15:47:49 UTC (rev 254)
@@ -26,8 +26,8 @@
# Remember to change the version number immediately *after* a release.
# Set my_issvn to "yes" for non-released code. Remember to run an
# "svn up" and "autogen.sh" right before creating a distribution.
-m4_define([my_version], [0.9.17])
-m4_define([my_issvn], [yes])
+m4_define([my_version], [1.0.0])
+m4_define([my_issvn], [no])
m4_define([svn_revision], m4_esyscmd([echo -n $((svn info 2>/dev/null \
|| echo 'Revision: 0')|sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)]))
@@ -39,16 +39,17 @@
# (Interfaces added: CURRENT++, AGE++, REVISION=0)
# (No interfaces changed: REVISION++)
# Please remember to document interface changes in the NEWS file.
-LIBKSBA_LT_CURRENT=16
-LIBKSBA_LT_AGE=8
+LIBKSBA_LT_CURRENT=17
+LIBKSBA_LT_AGE=9
LIBKSBA_LT_REVISION=0
#-------------------
+# If the API is changed in an incompatible way: increment the next counter.
+KSBA_CONFIG_API_VERSION=1
-# fixme: When bouncing this to a newer version, you check whether the
-# declaration tests for some symbols can be removed.
-NEED_GPG_ERROR_VERSION=0.7
+NEED_GPG_ERROR_VERSION=1.2
+
PACKAGE=$PACKAGE_NAME
VERSION=$PACKAGE_VERSION
@@ -136,10 +137,6 @@
AC_MSG_ERROR([libgpg-error is needed.
See ftp://ftp.gnupg.org/gcrypt/libgpg-error/ .])
fi
-_tmp_gpg_error_save_cflags="$CFLAGS"
-CFLAGS="$CFLAGS $GPG_ERROR_CFLAGS"
-AC_CHECK_DECLS(GPG_ERR_UNKNOWN_CRIT_EXTN,,,[#include <gpg-error.h>])
-CFLAGS="${_tmp_gpg_error_save_cflags}"
AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_KSBA,
[The default error source for libksba.])
@@ -173,6 +170,7 @@
KSBA_CONFIG_CFLAGS=""
AC_SUBST(KSBA_CONFIG_LIBS)
AC_SUBST(KSBA_CONFIG_CFLAGS)
+AC_SUBST(KSBA_CONFIG_API_VERSION)
# The Makefiles need to know about cross compiling
AM_CONDITIONAL(CROSS_COMPILING, test x$cross_compiling = xyes)
Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/src/ChangeLog 2006-08-31 15:47:49 UTC (rev 254)
@@ -1,3 +1,28 @@
+2006-08-31 Werner Koch <wk at g10code.com>
+
+ * ocsp.h (struct ocsp_extension_s): New.
+ * ocsp.c (extract_nonce): Renamed to ..
+ (parse_response_extensions): .. this. Extended to save all
+ extensions.
+ (release_ocsp_extensions): New.
+ (ksba_ocsp_release): Release new extension data.
+ (ksba_ocsp_parse_response): Reset extesnion data.
+ (parse_optional_boolean): New.
+ (parse_single_extensions): New.
+
+ * ksba.m4: Implement --api-version check.
+ * ksba-config.in (echo_api_version): New option --api-version.
+
+ * crl.c (GPG_ERR_UNKNOWN_CRIT_EXTN): Removed definition as we now
+ require a decent libgpg-error.
+
+ * ocsp.c (ksba_ocsp_get_responder_id): Implemented. Changed NAME
+ from ksba_name_t* to char** and SHA1KEYHASH from unsigned char* to
+ ksba_sexp_t*. Given that the function has always returned an
+ not_implemented error code and thus was not useful at all, we
+ don't consider this as an ABI change (still pointers) and the API
+ change is not real as this function was never useful.
+
2006-08-30 Werner Koch <wk at g10code.com>
* ocsp.c (extract_nonce): New.
Modified: trunk/src/crl.c
===================================================================
--- trunk/src/crl.c 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/src/crl.c 2006-08-31 15:47:49 UTC (rev 254)
@@ -35,9 +35,6 @@
#include "ber-decoder.h"
#include "crl.h"
-#if !HAVE_DECL_GPG_ERR_UNKNOWN_CRIT_EXTN
-#define GPG_ERR_UNKNOWN_CRIT_EXTN 172
-#endif
static const char oidstr_crlNumber[] = "2.5.29.20";
static const char oidstr_crlReason[] = "2.5.29.21";
Modified: trunk/src/ksba-config.in
===================================================================
--- trunk/src/ksba-config.in 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/src/ksba-config.in 2006-08-31 15:47:49 UTC (rev 254)
@@ -14,6 +14,8 @@
cflags="@KSBA_CONFIG_CFLAGS@ @GPG_ERROR_CFLAGS@"
prefix=@prefix@
exec_prefix=@exec_prefix@
+api_version="@KSBA_CONFIG_API_VERSION@"
+
includes=""
libdirs=""
exec_prefix_set=no
@@ -21,6 +23,7 @@
echo_cflags=no
echo_prefix=no
echo_exec_prefix=no
+echo_api_version=no
usage()
@@ -31,6 +34,7 @@
[--prefix[=DIR]]
[--exec-prefix[=DIR]]
[--version]
+ [--api-version]
[--libs]
[--cflags]
EOF
@@ -68,6 +72,9 @@
echo "@VERSION@"
exit 0
;;
+ --api-version)
+ echo_api_version=yes
+ ;;
--cflags)
echo_cflags=yes
;;
@@ -89,6 +96,10 @@
echo $exec_prefix
fi
+if test "$echo_api_version" = "yes"; then
+ echo "$api_version"
+fi
+
if test "$echo_cflags" = "yes"; then
includes=""
if test "@includedir@" != "/usr/include" ; then
Modified: trunk/src/ksba.h
===================================================================
--- trunk/src/ksba.h 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/src/ksba.h 2006-08-31 15:47:49 UTC (rev 254)
@@ -1,5 +1,5 @@
/* ksba.h - X509 library for the Aegypten project
- * Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 g10 Code GmbH
*
* This file is part of KSBA.
*
@@ -390,8 +390,8 @@
ksba_sexp_t ksba_ocsp_get_sig_val (ksba_ocsp_t ocsp,
ksba_isotime_t produced_at);
gpg_error_t ksba_ocsp_get_responder_id (ksba_ocsp_t ocsp,
- ksba_name_t *name,
- unsigned char *sha1keyhash);
+ char **r_name,
+ ksba_sexp_t *r_keyid);
ksba_cert_t ksba_ocsp_get_cert (ksba_ocsp_t ocsp, int idx);
gpg_error_t ksba_ocsp_get_status (ksba_ocsp_t ocsp, ksba_cert_t cert,
ksba_status_t *r_status,
@@ -402,7 +402,8 @@
gpg_error_t ksba_ocsp_get_extension (ksba_ocsp_t ocsp, ksba_cert_t cert,
int idx,
char const **r_oid, int *r_crit,
- size_t *r_deroff, size_t *r_derlen);
+ unsigned char const **r_der,
+ size_t *r_derlen);
/*-- certreq.c --*/
Modified: trunk/src/ksba.m4
===================================================================
--- trunk/src/ksba.m4 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/src/ksba.m4 2006-08-31 15:47:49 UTC (rev 254)
@@ -13,6 +13,12 @@
dnl AM_PATH_KSBA([MINIMUM-VERSION,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
dnl Test for libksba and define KSBA_CFLAGS and KSBA_LIBS
+dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed
+dnl with the API version to also check the API compatibility. Example:
+dnl a MINIMUN-VERSION of 1:1.0.7 won't pass the test unless the installed
+dnl version of libksba is at least 1.0.7 *and* the API number is 1. Using
+dnl this features allows to prevent build against newer versions of libksba
+dnl with a changed API.
dnl
AC_DEFUN([AM_PATH_KSBA],
[ AC_ARG_WITH(ksba-prefix,
@@ -27,7 +33,15 @@
fi
AC_PATH_PROG(KSBA_CONFIG, ksba-config, no)
- min_ksba_version=ifelse([$1], ,0.4.4,$1)
+ tmp=ifelse([$1], ,1:1.0.0,$1)
+ if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
+ req_ksba_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
+ min_ksba_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
+ else
+ req_ksba_api=0
+ min_ksba_version="$tmp"
+ fi
+
AC_MSG_CHECKING(for KSBA - version >= $min_ksba_version)
ok=no
if test "$KSBA_CONFIG" != "no" ; then
@@ -61,14 +75,33 @@
fi
fi
if test $ok = yes; then
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ if test $ok = yes; then
+ # Even if we have a recent libksba, we should check that the
+ # API is compatible.
+ if test "$req_ksba_api" -gt 0 ; then
+ tmp=`$KSBA_CONFIG --api-version 2>/dev/null || echo 0`
+ if test "$tmp" -gt 0 ; then
+ AC_MSG_CHECKING([KSBA API version])
+ if test "$req_ksba_api" -eq "$tmp" ; then
+ AC_MSG_RESULT(okay)
+ else
+ ok=no
+ AC_MSG_RESULT([does not match. want=$req_ksba_api got=$tmp.])
+ fi
+ fi
+ fi
+ fi
+ if test $ok = yes; then
KSBA_CFLAGS=`$KSBA_CONFIG $ksba_config_args --cflags`
KSBA_LIBS=`$KSBA_CONFIG $ksba_config_args --libs`
- AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
KSBA_CFLAGS=""
KSBA_LIBS=""
- AC_MSG_RESULT(no)
ifelse([$3], , :, [$3])
fi
AC_SUBST(KSBA_CFLAGS)
Modified: trunk/src/ocsp.c
===================================================================
--- trunk/src/ocsp.c 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/src/ocsp.c 2006-08-31 15:47:49 UTC (rev 254)
@@ -143,7 +143,44 @@
return err;
}
+
+/* Note that R_BOOL will only be set if a value has been given. Thus
+ the caller should set it to the default value prior to calling this
+ function. Obviously no call to parse_skip is required after
+ calling this function. */
static gpg_error_t
+parse_optional_boolean (unsigned char const **buf, size_t *len, int *r_bool)
+{
+ gpg_error_t err;
+ struct tag_info ti;
+
+ err = _ksba_ber_parse_tl (buf, len, &ti);
+ if (err)
+ ;
+ else if (!ti.length)
+ err = gpg_error (GPG_ERR_TOO_SHORT);
+ else if (ti.length > *len)
+ err = gpg_error (GPG_ERR_BAD_BER);
+ else if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_BOOLEAN
+ && !ti.is_constructed)
+ {
+ if (ti.length != 1)
+ err = gpg_error (GPG_ERR_BAD_BER);
+ *r_bool = !!**buf;
+ parse_skip (buf, len, &ti);
+ }
+ else
+ { /* Undo the read. */
+ *buf -= ti.nhdr;
+ *len += ti.nhdr;
+ }
+
+ return err;
+}
+
+
+
+static gpg_error_t
parse_object_id_into_str (unsigned char const **buf, size_t *len, char **oid)
{
struct tag_info ti;
@@ -238,6 +275,18 @@
}
+static void
+release_ocsp_extensions (struct ocsp_extension_s *ex)
+{
+ while (ex)
+ {
+ struct ocsp_extension_s *tmp = ex->next;
+ xfree (ex);
+ ex = tmp;
+ }
+}
+
+
/* Release the OCSP object and all its resources. Passing NULL for
OCSP is a valid nop. */
void
@@ -254,10 +303,14 @@
ocsp->requestlist = ri->next;
ksba_cert_release (ri->cert);
ksba_cert_release (ri->issuer_cert);
+ release_ocsp_extensions (ri->single_extensions);
xfree (ri->serialno);
}
xfree (ocsp->sigval);
+ xfree (ocsp->responder_id.name);
+ xfree (ocsp->responder_id.keyid);
release_ocsp_certlist (ocsp->received_certs);
+ release_ocsp_extensions (ocsp->response_extensions);
xfree (ocsp);
}
@@ -775,8 +828,10 @@
-/* Extract the nonce from the extension sequence. A typical data
- ASN.1 blob passed to this function is:
+/*
+ Parse the response extensions and store them aways. While doing
+ this we also check the nonce extension. A typical data ASN.1 blob
+ with only the nonce extension as passed to this function is:
SEQUENCE {
SEQUENCE {
@@ -790,19 +845,24 @@
*/
static int
-extract_nonce (ksba_ocsp_t ocsp, const unsigned char *data, size_t datalen)
+parse_response_extensions (ksba_ocsp_t ocsp,
+ const unsigned char *data, size_t datalen)
{
gpg_error_t err;
struct tag_info ti;
size_t length;
char *oid = NULL;
+ assert (!ocsp->response_extensions);
err = parse_sequence (&data, &datalen, &ti);
if (err)
goto leave;
length = ti.length;
while (length)
{
+ struct ocsp_extension_s *ex;
+ int is_crit;
+
err = parse_sequence (&data, &datalen, &ti);
if (err)
goto leave;
@@ -817,6 +877,10 @@
err = parse_object_id_into_str (&data, &datalen, &oid);
if (err)
goto leave;
+ is_crit = 0;
+ err = parse_optional_boolean (&data, &datalen, &is_crit);
+ if (err)
+ goto leave;
err = parse_octet_string (&data, &datalen, &ti);
if (err)
goto leave;
@@ -831,6 +895,21 @@
else
ocsp->good_nonce = 1;
}
+ ex = xtrymalloc (sizeof *ex + strlen (oid) + ti.length);
+ if (!ex)
+ {
+ err = gpg_error_from_errno (errno);
+ goto leave;
+ }
+ ex->crit = is_crit;
+ strcpy (ex->data, oid);
+ ex->data[strlen (oid)] = 0;
+ ex->off = strlen (oid) + 1;
+ ex->len = ti.length;
+ memcpy (ex->data + ex->off, data, ti.length);
+ ex->next = ocsp->response_extensions;
+ ocsp->response_extensions = ex;
+
parse_skip (&data, &datalen, &ti); /* Skip the octet string / integer. */
}
@@ -840,6 +919,73 @@
}
+/*
+ Parse single extensions and store them away.
+*/
+static int
+parse_single_extensions (struct ocsp_reqitem_s *ri,
+ const unsigned char *data, size_t datalen)
+{
+ gpg_error_t err;
+ struct tag_info ti;
+ size_t length;
+ char *oid = NULL;
+
+ assert (ri && !ri->single_extensions);
+ err = parse_sequence (&data, &datalen, &ti);
+ if (err)
+ goto leave;
+ length = ti.length;
+ while (length)
+ {
+ struct ocsp_extension_s *ex;
+ int is_crit;
+
+ err = parse_sequence (&data, &datalen, &ti);
+ if (err)
+ goto leave;
+ if (length < ti.nhdr + ti.length)
+ {
+ err = gpg_error (GPG_ERR_BAD_BER);
+ goto leave;
+ }
+ length -= ti.nhdr + ti.length;
+
+ xfree (oid);
+ err = parse_object_id_into_str (&data, &datalen, &oid);
+ if (err)
+ goto leave;
+ is_crit = 0;
+ err = parse_optional_boolean (&data, &datalen, &is_crit);
+ if (err)
+ goto leave;
+ err = parse_octet_string (&data, &datalen, &ti);
+ if (err)
+ goto leave;
+ ex = xtrymalloc (sizeof *ex + strlen (oid) + ti.length);
+ if (!ex)
+ {
+ err = gpg_error_from_errno (errno);
+ goto leave;
+ }
+ ex->crit = is_crit;
+ strcpy (ex->data, oid);
+ ex->data[strlen (oid)] = 0;
+ ex->off = strlen (oid) + 1;
+ ex->len = ti.length;
+ memcpy (ex->data + ex->off, data, ti.length);
+ ex->next = ri->single_extensions;
+ ri->single_extensions = ex;
+
+ parse_skip (&data, &datalen, &ti); /* Skip the octet string / integer. */
+ }
+
+ leave:
+ xfree (oid);
+ return err;
+}
+
+
/* Parse the first part of a response:
OCSPResponse ::= SEQUENCE {
@@ -1178,7 +1324,13 @@
return gpg_error (GPG_ERR_BAD_BER);
if (ti.class == CLASS_CONTEXT && ti.tag == 1 && ti.is_constructed)
{
- parse_skip (data, datalen, &ti); /* FIXME */
+ if (request_item)
+ {
+ err = parse_single_extensions (request_item, *data, ti.length);
+ if (err)
+ return err;
+ }
+ parse_skip (data, datalen, &ti);
}
else
err = gpg_error (GPG_ERR_INV_OBJ);
@@ -1232,6 +1384,8 @@
}
/* The responderID field. */
+ assert (!ocsp->responder_id.name);
+ assert (!ocsp->responder_id.keyid);
err = _ksba_ber_parse_tl (data, datalen, &ti);
if (err)
return err;
@@ -1239,11 +1393,24 @@
return gpg_error (GPG_ERR_BAD_BER);
else if (ti.class == CLASS_CONTEXT && ti.tag == 1 && ti.is_constructed)
{ /* byName. */
- parse_skip (data, datalen, &ti); /* FIXME */
+ err = _ksba_derdn_to_str (*data, ti.length, &ocsp->responder_id.name);
+ if (err)
+ return err;
+ parse_skip (data, datalen, &ti);
}
else if (ti.class == CLASS_CONTEXT && ti.tag == 2 && ti.is_constructed)
{ /* byKey. */
- parse_skip (data, datalen, &ti); /* FIXME */
+ err = parse_octet_string (data, datalen, &ti);
+ if (err)
+ return err;
+ if (!ti.length)
+ return gpg_error (GPG_ERR_INV_OBJ); /* Zero length key id. */
+ ocsp->responder_id.keyid = xtrymalloc (ti.length);
+ if (!ocsp->responder_id.keyid)
+ return gpg_error_from_errno (errno);
+ memcpy (ocsp->responder_id.keyid, *data, ti.length);
+ ocsp->responder_id.keyidlen = ti.length;
+ parse_skip (data, datalen, &ti);
}
else
err = gpg_error (GPG_ERR_INV_OBJ);
@@ -1274,7 +1441,7 @@
err = parse_context_tag (data, datalen, &ti, 1);
if (!err)
{
- err = extract_nonce (ocsp, *data, ti.length);
+ err = parse_response_extensions (ocsp, *data, ti.length);
if (err)
return err;
parse_skip (data, datalen, &ti);
@@ -1439,16 +1606,20 @@
if (!ocsp->requestlist)
return gpg_error (GPG_ERR_MISSING_ACTION);
+ /* Reset the fields used to track the response. This is so that we
+ can use the parse function a second time for the same
+ request. This is useful in case of a TryLater response status. */
ocsp->response_status = KSBA_OCSP_RSPSTATUS_NONE;
release_ocsp_certlist (ocsp->received_certs);
+ release_ocsp_extensions (ocsp->response_extensions);
ocsp->received_certs = NULL;
ocsp->hash_length = 0;
ocsp->bad_nonce = 0;
ocsp->good_nonce = 0;
-
- /* Reset the fields used to track the response. This is so that we
- can use the parse function a second time for the same
- request. This is useful in case of a TryLater response status. */
+ xfree (ocsp->responder_id.name);
+ ocsp->responder_id.name = NULL;
+ xfree (ocsp->responder_id.keyid);
+ ocsp->responder_id.keyid = NULL;
for (ri=ocsp->requestlist; ri; ri = ri->next)
{
ri->status = KSBA_STATUS_NONE;
@@ -1456,8 +1627,10 @@
*ri->next_update = 0;
*ri->revocation_time = 0;
ri->revocation_reason = 0;
+ release_ocsp_extensions (ri->single_extensions);
}
+ /* Run the actual parser. */
err = parse_response (ocsp, msg, msglen);
*response_status = ocsp->response_status;
@@ -1534,21 +1707,50 @@
}
-/* Return the responder ID for the current response into NAME or into
- the provided 20 byte buffer SHA1KEYHASH. On sucess NAME either
- contains the responder ID as a standard name or if NAME is NULL,
- SHA1KEYHASH contains the hash of the public key. SHA1KEYHASH may
- be given as NULL if support for a KEYHASH is not intended. Caller
- must release NAME. */
+/* Return the responder ID for the current response into R_NAME or
+ into R_KEYID. On sucess either R_NAME or R_KEYID will receive an
+ allocated object. If R_NAME or R_KEYID has been passed as NULL but
+ a value is available the errorcode GPG_ERR_NO_DATA is returned.
+ Caller must release the values stored at R_NAME or R_KEYID; the
+ function stores NULL tehre in case of an error. */
gpg_error_t
ksba_ocsp_get_responder_id (ksba_ocsp_t ocsp,
- ksba_name_t *name, unsigned char *sha1keyhash)
+ char **r_name, ksba_sexp_t *r_keyid)
{
+ if (r_name)
+ *r_name = NULL;
+ if (r_keyid)
+ *r_keyid = NULL;
+
if (!ocsp)
return gpg_error (GPG_ERR_INV_VALUE);
+ if (ocsp->responder_id.name && r_name)
+ {
+ *r_name = xtrystrdup (ocsp->responder_id.name);
+ if (!*r_name)
+ return gpg_error_from_errno (errno);
+ }
+ else if (ocsp->responder_id.keyid && r_keyid)
+ {
+ char numbuf[50];
+ size_t numbuflen;
- return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ sprintf (numbuf,"(%lu:", (unsigned long)ocsp->responder_id.keyidlen);
+ numbuflen = strlen (numbuf);
+ *r_keyid = xtrymalloc (numbuflen + ocsp->responder_id.keyidlen + 2);
+ if (!*r_keyid)
+ return gpg_error_from_errno (errno);
+ strcpy (*r_keyid, numbuf);
+ memcpy (*r_keyid+numbuflen,
+ ocsp->responder_id.keyid, ocsp->responder_id.keyidlen);
+ (*r_keyid)[numbuflen + ocsp->responder_id.keyidlen] = ')';
+ (*r_keyid)[numbuflen + ocsp->responder_id.keyidlen + 1] = 0;
+ }
+ else
+ gpg_error (GPG_ERR_NO_DATA);
+
+ return 0;
}
@@ -1628,40 +1830,56 @@
}
+/* WARNING: The returned values ares only valid as long as no other
+ ocsp function is called on the same context. */
gpg_error_t
ksba_ocsp_get_extension (ksba_ocsp_t ocsp, ksba_cert_t cert, int idx,
char const **r_oid, int *r_crit,
- size_t *r_deroff, size_t *r_derlen)
+ unsigned char const **r_der, size_t *r_derlen)
{
- gpg_error_t err;
+ struct ocsp_extension_s *ex;
if (!ocsp)
return gpg_error (GPG_ERR_INV_VALUE);
if (!ocsp->requestlist)
return gpg_error (GPG_ERR_MISSING_ACTION);
+ if (idx < 0)
+ return gpg_error (GPG_ERR_INV_INDEX);
if (cert)
{
/* Return extensions for the certificate (singleExtensions). */
-/* for (ri=ocsp->requestlist; ri; ri = ri->next) */
-/* if (ri->cert == cert) */
-/* break; */
-/* if (!ri) */
-/* return gpg_error (GPG_ERR_NOT_FOUND); */
+ struct ocsp_reqitem_s *ri;
-
+ for (ri=ocsp->requestlist; ri; ri = ri->next)
+ if (ri->cert == cert)
+ break;
+ if (!ri)
+ return gpg_error (GPG_ERR_NOT_FOUND);
+
+ for (ex=ri->single_extensions; ex && idx; ex = ex->next, idx--)
+ ;
+ if (!ex)
+ return gpg_error (GPG_ERR_EOF); /* No more extensions. */
}
else
{
/* Return extensions for the response (responseExtensions). */
-
-
-
+ for (ex=ocsp->response_extensions; ex && idx; ex = ex->next, idx--)
+ ;
+ if (!ex)
+ return gpg_error (GPG_ERR_EOF); /* No more extensions. */
}
- return gpg_error (GPG_ERR_EOF);
+ if (r_oid)
+ *r_oid = ex->data;
+ if (r_crit)
+ *r_crit = ex->crit;
+ if (r_der)
+ *r_der = ex->data + ex->off;
+ if (r_derlen)
+ *r_derlen = ex->len;
-/* if (idx < 0 || idx >= cert->cache.n_extns) */
-/* return gpg_error (GPG_ERR_INV_INDEX); */
+ return 0;
}
Modified: trunk/src/ocsp.h
===================================================================
--- trunk/src/ocsp.h 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/src/ocsp.h 2006-08-31 15:47:49 UTC (rev 254)
@@ -25,6 +25,25 @@
#include "ksba.h"
+
+/* A structure to store certificates read from a response. */
+struct ocsp_certlist_s {
+ struct ocsp_certlist_s *next;
+ ksba_cert_t cert;
+};
+
+/* A structre to save a way extensions. */
+struct ocsp_extension_s
+{
+ struct ocsp_extension_s *next;
+ size_t off; /* Offset into DATA to the content of the octet string. */
+ size_t len; /* Length of the octet string. */
+ int crit; /* IsCritical flag. */
+ char data[1]; /* This is made up of the OID string followed by the
+ actual DER data of the extension. */
+};
+
+
/* A structure to keep a information about a single status request. */
struct ocsp_reqitem_s {
struct ocsp_reqitem_s *next;
@@ -44,17 +63,9 @@
ksba_status_t status; /* Set to the status of the target. */
ksba_isotime_t revocation_time; /* The indicated revocation time. */
ksba_crl_reason_t revocation_reason; /* The reason given for revocation. */
+ struct ocsp_extension_s *single_extensions; /* List of extensions. */
};
-
-/* A structure to store certificates read from a response. */
-struct ocsp_certlist_s {
- struct ocsp_certlist_s *next;
- ksba_cert_t cert;
-};
-
-
-
/* A structure used as context for the ocsp subsystem. */
struct ksba_ocsp_s {
char *digest_oid; /* The OID of the digest algorithm to be
@@ -68,8 +79,6 @@
increased, check that the created
request will still be valid as we use a
hacked implementation. */
- int bad_nonce; /* The nonce does not match the request. */
- int good_nonce; /* The nonce does match the request. */
unsigned char *request_buffer; /* Internal buffer to build the request. */
size_t request_buflen;
@@ -82,6 +91,14 @@
ksba_isotime_t produced_at; /* The time the response was signed. */
struct ocsp_certlist_s *received_certs; /* Certificates received in
the response. */
+ struct ocsp_extension_s *response_extensions; /* List of extensions. */
+ int bad_nonce; /* The nonce does not match the request. */
+ int good_nonce; /* The nonce does match the request. */
+ struct {
+ char *name; /* Allocated DN. */
+ char *keyid; /* Allocated key ID. */
+ size_t keyidlen; /* length of the KeyID. */
+ } responder_id; /* The reponder ID from the response. */
};
Modified: trunk/tests/ChangeLog
===================================================================
--- trunk/tests/ChangeLog 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/tests/ChangeLog 2006-08-31 15:47:49 UTC (rev 254)
@@ -1,3 +1,9 @@
+2006-08-31 Werner Koch <wk at g10code.com>
+
+ * t-ocsp.c (one_response): Print the responder id.
+ (one_response): Print extension info.
+ (get_oid_desc): New.
+
2006-08-30 Werner Koch <wk at g10code.com>
* t-ocsp.c (one_response): Build the test request with the same nonce.
Modified: trunk/tests/t-common.h
===================================================================
--- trunk/tests/t-common.h 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/tests/t-common.h 2006-08-31 15:47:49 UTC (rev 254)
@@ -80,7 +80,7 @@
void
-print_hex (unsigned char *p, size_t n)
+print_hex (const unsigned char *p, size_t n)
{
if (!p)
fputs ("none", stdout);
Modified: trunk/tests/t-ocsp.c
===================================================================
--- trunk/tests/t-ocsp.c 2006-08-30 20:39:53 UTC (rev 253)
+++ trunk/tests/t-ocsp.c 2006-08-31 15:47:49 UTC (rev 254)
@@ -32,11 +32,28 @@
#include "t-common.h"
+#include "oidtranstbl.h"
+
int verbose;
int debug;
int no_nonce;
+/* Return the description for OID; if no description is available
+ NULL is returned. */
+static const char *
+get_oid_desc (const char *oid)
+{
+ int i;
+
+ if (oid)
+ for (i=0; oidtranstbl[i].oid; i++)
+ if (!strcmp (oidtranstbl[i].oid, oid))
+ return oidtranstbl[i].desc;
+ return NULL;
+}
+
+
static unsigned char *
read_file (const char *fname, size_t *r_length)
{
@@ -210,16 +227,26 @@
ksba_crl_reason_t reason;
ksba_isotime_t this_update, next_update, revocation_time, produced_at;
ksba_sexp_t sigval;
+ char *name;
+ ksba_sexp_t keyid;
+ err = ksba_ocsp_get_responder_id (ocsp, &name, &keyid);
+ fail_if_err (err);
+ printf ("responder id .....: ");
+ if (name)
+ printf ("`%s'", name);
+ else
+ print_sexp (keyid);
+ putchar ('\n');
+ ksba_free (name);
+ ksba_free (keyid);
+
sigval = ksba_ocsp_get_sig_val (ocsp, produced_at);
printf ("signature value ..: ");
print_sexp (sigval);
printf ("\nproduced at ......: ");
print_time (produced_at);
putchar ('\n');
-
-
-
err = ksba_ocsp_get_status (ocsp, cert,
&status, this_update, next_update,
revocation_time, &reason);
@@ -264,6 +291,45 @@
ksba_cert_release (acert);
printf ("extra certificates: %d\n", cert_idx );
}
+
+ {
+ int idx, crit;
+ const char *oid;
+ const unsigned char *der;
+ size_t derlen;
+
+ for (idx=0; !(err=ksba_ocsp_get_extension (ocsp, NULL, idx,
+ &oid, &crit,
+ &der, &derlen)); idx++)
+ {
+ const char *s = get_oid_desc (oid);
+ printf ("%sresp-extn ..%s: %s%s%s%s (",
+ crit? "crit. ":"",
+ crit?"":"......",
+ s?"(":"", s?s:"", s?") ":"", oid);
+ print_hex (der, derlen);
+ putchar (')');
+ putchar ('\n');
+ }
+ if (err && gpg_err_code (err) != GPG_ERR_EOF)
+ fail_if_err (err);
+
+ for (idx=0; !(err=ksba_ocsp_get_extension (ocsp, cert, idx,
+ &oid, &crit,
+ &der, &derlen)); idx++)
+ {
+ const char *s = get_oid_desc (oid);
+ printf ("%ssngl-extn ..%s: %s%s%s%s (",
+ crit? "crit. ":"",
+ crit?"":"......",
+ s?"(":"", s?s:"", s?") ":"", oid);
+ print_hex (der, derlen);
+ putchar (')');
+ putchar ('\n');
+ }
+ if (err && gpg_err_code (err) != GPG_ERR_EOF)
+ fail_if_err (err);
+ }
}
More information about the Gnupg-commits
mailing list