* ksba.texi: Added 2 more fucntions. Minor other updates.
authorWerner Koch <wk@gnupg.org>
Tue, 23 Mar 2004 18:11:09 +0000 (18:11 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 23 Mar 2004 18:11:09 +0000 (18:11 +0000)
* cert-basic.c (print_oid_and_desc): New.
(list_extensions): Print info_access.
(print_names): Hack to optionally indent the first line too.
(print_oid_list): New.
(list_extensions): Use it.

NEWS
doc/ChangeLog
doc/ksba.texi
src/ChangeLog
src/ber-help.c
src/cert.c
src/ksba.h
src/libksba.vers
tests/ChangeLog
tests/Makefile.am
tests/cert-basic.c

diff --git a/NEWS b/NEWS
index c574d39..1ad71dc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,9 +4,11 @@ Noteworthy changes in version 0.9.5
 
  * Interface changes relative to the 0.9.4 release:
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-ksba_ocsp_get_responder_id   NEW.
-ksba_ocsp_get_cert           NEW.
-
+ksba_ocsp_get_responder_id           NEW.
+ksba_ocsp_get_cert                   NEW.
+ksba_cert_get_authority_info_access  NEW.
+ksba_cert_get_subject_info_access    NEW.
 
 Noteworthy changes in version 0.9.4 (2004-02-20)
 ------------------------------------------------
index 6a277b9..5c7c27a 100644 (file)
@@ -1,3 +1,7 @@
+2004-03-23  Werner Koch  <wk@gnupg.org>
+
+       * ksba.texi: Added 2 more fucntions. Minor other updates.
+
 2004-01-28  Werner Koch  <wk@gnupg.org>
 
        * ksba.info (components): Add a table of used labels.
index 84733f4..c24043e 100644 (file)
@@ -125,11 +125,6 @@ Mastering the Cryptographic Message Syntax
 * CMS Basics::                  
 * CMS Parser::                  
 
-Error Handling
-
-* Error values::                A list of all error values used.
-* Error strings::               How to get a descriptive string from a value.
-
 @end detailmenu
 @end menu
 
@@ -321,7 +316,7 @@ The @code{KsbaCert} type is a handle for an X.509 certificate.
 This section explains how to create a certificate object, initialize it
 copy it and eventually destroy it. 
 
-@deftypefun KsbaCert ksba_cert_new (void)
+@deftypefun ksba_cert_tksba_cert_new (void)
 The function @code{ksba_cert_new} creates a new @code{KsbaCert}
 object and returns a handle for it.
 
@@ -329,20 +324,20 @@ The only reason why this function may fail is an out-of-memory condition in
 which case @code{NULL} is returned.
 @end deftypefun
 
-@deftypefun void ksba_cert_ref (KsbaCert cert)
+@deftypefun void ksba_cert_ref (ksba_cert_tcert)
 The function @code{ksba_cert_ref} bumps the reference counter of the
 certificate object up by one.  Thus an extra @code{ksba_cert_release} is
 required to actually release the memory used for the object.
 @end deftypefun
 
-@deftypefun void ksba_cert_release (@w{KsbaCert @var{cert}})
+@deftypefun void ksba_cert_release (@w{ksba_cert_t@var{cert}})
 The function @code{ksba_cert_release} destroys the certificate object with the
 handle @var{cert} and releases all associated resources.  Due to the use of
 reference counting no actual memory may be released.  It is okay to pass
 @code{NULL} to the function in which case nothing happens.
 @end deftypefun
 
-@deftypefun KsbaError ksba_cert_read_der (@w{KsbaCert @var{cert}}, @w{KsbaReader @var{reader}})
+@deftypefun gpg_error_t ksba_cert_read_der (@w{ksba_cert_t@var{cert}}, @w{KsbaReader @var{reader}})
 
 Read the next certificate from @var{reader} and store it in the
 certificate object @var{cert} for future access.  The certificate is parsed
@@ -353,7 +348,7 @@ The function returns zero if the operation was successfully performed or
 an error code.
 @end deftypefun
 
-@deftypefun KsbaError ksba_cert_init_from_mem (@w{KsbaCert @var{cert}}, @w{const void *@var{buffer}}, @w{size_t @var{length}})
+@deftypefun gpg_error_t ksba_cert_init_from_mem (@w{ksba_cert_t@var{cert}}, @w{const void *@var{buffer}}, @w{size_t @var{length}})
 
 Parse the @var{buffer} which should contain a @acronym{DER} encoded
 certificate of @var{length} and initialize the @var{cert}.  This
@@ -374,7 +369,7 @@ certificate in a well defined manner.  An error will be retruned if the
 certificate object has not yet been initialzied by means of
 @code{ksba_cert_read_der} or @code{ksba_cert_init_from_mem}.
 
-@deftypefun const unsigned char *ksba_cert_get_image (@w{KsbaCert @var{cert}}, @w{size_t *@var{r_length}}) 
+@deftypefun const unsigned char *ksba_cert_get_image (@w{ksba_cert_t@var{cert}}, @w{size_t *@var{r_length}}) 
 
 This function returns a pointer
 to the @acronym{DER} encoded buffer with the raw certificate as well as
@@ -385,7 +380,7 @@ The function returns @code{NULL} on error or a pointer which is valid as
 long as @var{cert} is valid.
 @end deftypefun
 
-@deftypefun KsbaError ksba_cert_hash (@w{KsbaCert @var{cert}}, @w{int @var{what}}, @w{void (*@var{hasher})(void *, const void *, size_t length)}, @w{void *@var{hasher_arg}})
+@deftypefun gpg_error_t ksba_cert_hash (@w{ksba_cert_t@var{cert}}, @w{int @var{what}}, @w{void (*@var{hasher})(void *, const void *, size_t length)}, @w{void *@var{hasher_arg}})
 
 This function feeds the data which is expected to be hashed into the
 given function @var{hasher}, where the first argument passed is
@@ -400,7 +395,7 @@ function is not expected to yiled errors anyway.
 @end deftypefun
 
 
-@deftypefun const char *ksba_cert_get_digest_algo (KsbaCert cert)
+@deftypefun const char *ksba_cert_get_digest_algo (ksba_cert_tcert)
 
 Figure out the the digest algorithm used for the signature and return
 its @acronym{OID} in dotted decimal format.  This function is most
@@ -411,7 +406,7 @@ string with the @acronym{OID}.  This string is valid as long the
 certificate object is valid.
 @end deftypefun
 
-@deftypefun KsbaSexp ksba_cert_get_serial (KsbaCert cert)
+@deftypefun KsbaSexp ksba_cert_get_serial (ksba_cert_tcert)
 
 The function returns the serial number of the certificate @var{cert}.
 The serial number is an integer returned as an cancnical encoded
@@ -419,7 +414,7 @@ S-expression with just one element.  The caller must free the returned
 value.  @code{NULL} is returned in case of error.
 @end deftypefun
 
-@deftypefun char *ksba_cert_get_issuer (KsbaCert cert, int idx)
+@deftypefun char *ksba_cert_get_issuer (ksba_cert_tcert, int idx)
 
 With @var{idx} given as @code{0}, this function returns the
 Distinguished Name (@acronym{DN}) of the certificate issuer which
@@ -446,7 +441,7 @@ The caller must free the returned string using @code{ksba_free} or
 whatever function has been registered as a replacement.
 @end deftypefun
 
-@deftypefun char *ksba_cert_get_subject (KsbaCert cert, int idx)
+@deftypefun char *ksba_cert_get_subject (ksba_cert_tcert, int idx)
 
 With @var{idx} given as @code{0}, this function returns the
 Distinguished Name (@acronym{DN}) of the certificate's subject.  The
@@ -472,7 +467,7 @@ whatever function has been registered as a replacement.
 @end deftypefun
 
 
-@deftypefun time_t ksba_cert_get_validity (KsbaCert @var{cert}, int @var{what})
+@deftypefun time_t ksba_cert_get_validity (ksba_cert_t@var{cert}, int @var{what})
 
 Return the validity dates from the certificate.  If no value is
 available @code{0} is returned because we can safely assume that the
@@ -483,26 +478,26 @@ To return the `notBefore' date, the value @code{0} must be supplied for
 @var{what};  @code{1} yields the `notAfter' value.
 @end deftypefun
 
-@deftypefun KsbaSexp ksba_cert_get_public_key (KsbaCert cert)
+@deftypefun KsbaSexp ksba_cert_get_public_key (ksba_cert_tcert)
 
 @c !FIXME!
 [This needs to get written - for now please see libksba/src/cert.c]
 
 @end deftypefun
 
-@deftypefun KsbaSexp ksba_cert_get_sig_val (KsbaCert cert)
+@deftypefun KsbaSexp ksba_cert_get_sig_val (ksba_cert_tcert)
 
 @c !FIXME!
 [This needs to get written - for now please see libksba/src/cert.c]
 @end deftypefun
 
-@deftypefun KsbaError ksba_cert_get_extension (KsbaCert cert, int idx, char const **r_oid, int *r_crit, size_t *r_deroff, size_t *r_derlen)
+@deftypefun gpg_error_t ksba_cert_get_extension (ksba_cert_tcert, int idx, char const **r_oid, int *r_crit, size_t *r_deroff, size_t *r_derlen)
 
 @c !FIXME!
 [This needs to get written - for now please see libksba/src/cert.c]
 @end deftypefun
 
-@deftypefun KsbaError ksba_cert_is_ca (KsbaCert cert, int *r_ca, int *r_pathlen)
+@deftypefun gpg_error_t ksba_cert_is_ca (ksba_cert_tcert, int *r_ca, int *r_pathlen)
 
 Return information on the basicConstraint (2.5.19.19) of CERT.  R_CA
 receives true if this is a CA and only in that case R_PATHLEN is set to
@@ -511,14 +506,14 @@ limitation
 
 @end deftypefun
 
-@deftypefun KsbaError ksba_cert_get_key_usage (KsbaCert cert, unsigned int *r_flags)
+@deftypefun gpg_error_t ksba_cert_get_key_usage (ksba_cert_tcert, unsigned int *r_flags)
 
 Get the key usage flags. The function returns Ksba_No_Data if no
 key usage is specified. 
 @end deftypefun
 
 
-@deftypefun KsbaError ksba_cert_get_cert_policies (KsbaCert cert, char **r_policies)
+@deftypefun gpg_error_t ksba_cert_get_cert_policies (ksba_cert_tcert, char **r_policies)
 
 Return a string with the certificatePolicies delimited by linefeeds.
 The return values may be extended to carry more information er line, so
@@ -529,12 +524,12 @@ Caller must free the returned value.
 @end deftypefun
 
 
-@deftypefun KsbaError ksba_cert_get_crl_dist_point (KsbaCert @var{cert}, int @var{idx}, KsbaName *@var{r_distpoint}, KsbaName *@var{r_issuer}, unsigned int *@var{r_reason})
+@deftypefun gpg_error_t ksba_cert_get_crl_dist_point (ksba_cert_t@var{cert}, int @var{idx}, ksba_name_t *@var{r_distpoint}, ksba_name_t *@var{r_issuer}, unsigned int *@var{r_reason})
 
 Return the CRLDistPoints given in the certificate extension of
 certificate @var{cert}.  @var{idx} should be iterated starting from 0
 until the function returns @code{-1}.  @var{r_distpoint} returns a
-KsbaName object with the distribution point name(s); the return value
+ksba_name_t object with the distribution point name(s); the return value
 may be @code{NULL} to indicate that this name is not available.
 @var{r_issuer} returns the CRL issuer; if the returned value is
 @code{NULL} the caller should assume that the CRL issuer is the same as
@@ -548,7 +543,7 @@ and @var{r_issuer} must be released by the caller using
 @code{ksba_name_release}.
 @end deftypefun
 
-@deftypefun KsbaError ksba_cert_get_auth_key_id (KsbaCert @var{cert}, KsbaSexp *@var{r_keyid}, KsbaName *@var{r_name}, KsbaSexp *@var{r_serial})
+@deftypefun gpg_error_t ksba_cert_get_auth_key_id (ksba_cert_t@var{cert}, KsbaSexp *@var{r_keyid}, ksba_name_t *@var{r_name}, KsbaSexp *@var{r_serial})
 
 Return the authorityKeyIdentifier in @var{r_name} and @var{r_serial} or
 in @var{r_keyid}.  @code{KSBA_No_Data} is returned if no
@@ -559,6 +554,37 @@ Note that r_keyid is not yet implemented and @var{NULL} must be passed instead.
 @end deftypefun
 
 
+@deftypefun gpg_error_t ksba_cert_get_authority_info_access (ksba_cert_t @var{cert}, int @var{idx}, char **@var{r_method}, ksba_name_t *@var{r_location})
+
+Return the authorityInfoAccess attributes. @var{idx} should be
+iterated starting from 0 until this function returns
+@code{GPG_ERR_EOF}.  @var{r_method} returns an allocated string with
+the OID of one item and @var{r_location} returns the GeneralName for
+that OID.  The returned values for @var{r_method} and @var{r_location}
+must be released by the caller unless the function returned an error;
+the function will however make sure that @var{r_method} and
+@var{r_location} will point to @code{NULL} if the function retruns an
+error. 
+
+See RFC-2459, section 4.2.2.1 for the defintion of this attribute.
+@end deftypefun
+
+@deftypefun gpg_error_t ksba_cert_get_subject_info_access (ksba_cert_t @var{cert}, int @var{idx}, char **@var{r_method}, ksba_name_t *@var{r_location})
+
+Return the subjectInfoAccess attributes. @var{idx} should be
+iterated starting from 0 until this function returns
+@code{GPG_ERR_EOF}.  @var{r_method} returns an allocated string with
+the OID of one item and @var{r_location} returns the GeneralName for
+that OID.  The returned values for @var{r_method} and @var{r_location}
+must be released by the caller unless the function returned an error;
+the function will however make sure that @var{r_method} and
+@var{r_location} will point to @code{NULL} if the function retruns an
+error. 
+
+See RFC-2459, section 4.2.2.2 for the defintion of this attribute.
+@end deftypefun
+
+
 
 @node Setting attributes
 @section How to set certificate attributes
@@ -610,7 +636,7 @@ perfectly okay to pass @code{NULL} to this function in which case
 nothing happens.
 @end deftypefun
 
-@deftypefun KsbaError ksba_cms_set_reader_writer (KsbaCMS @var{cms}, KsbaReader @var{r}, KsbaWriter @var{w})
+@deftypefun gpg_error_t ksba_cms_set_reader_writer (KsbaCMS @var{cms}, KsbaReader @var{r}, KsbaWriter @var{w})
 
 About all usages of the CMS framework require some input and output data
 (great surprise!).  Do accomplish this in the most abstract way, no
@@ -637,7 +663,7 @@ limited in size; e.g. it does not make sense to use a video clip as the
 @acronym{DN} despite the fact that the standard does not forbid it.
 
 
-@deftypefun KsbaError ksba_cms_parse (KsbaCMS @var{cms}, KsbaStopReason *@var{r_stopreason})
+@deftypefun gpg_error_t ksba_cms_parse (KsbaCMS @var{cms}, KsbaStopReason *@var{r_stopreason})
 
 This is the core function of the parser and commonly used in a loop.
 The parsing process is divided into serveral phases to allow the user to
@@ -762,17 +788,17 @@ This is an object to handle some of the names used in X.509.  We need
 this object approach because those names may come as a set and there is
 no other clean way to access them.
 
-@deftp {Data type} KsbaName
-The @code{KsbaName} type is an object to represent names sets.
+@deftp {Data type} ksba_name_t
+The @code{ksba_name_t} type is an object to represent names sets.
 @end deftp
 
 
-@deftypefun void ksba_name_release (KsbaName @var{name})
+@deftypefun void ksba_name_release (ksba_name_t @var{name})
 This function releases the object @var{name}.  Passing @code{NULL} is
 allowed.
 @end deftypefun
 
-@deftypefun const char *ksba_name_enum (KsbaName @var{name}, int @var{idx})
+@deftypefun const char *ksba_name_enum (ksba_name_t @var{name}, int @var{idx})
 
 By iterating @var{idx} up starting with 0, this function returns all
 General Names stored in @var{name}.  The format of the returned name is either
@@ -791,7 +817,7 @@ probably an Universal Resource Identifier which has the S-expression:
 The returned string has the same lifetime as @var{name}. 
 @end deftypefun
 
-@deftypefun char *ksba_name_get_uri (KsbaName @var{name}, int @var{idx})
+@deftypefun char *ksba_name_get_uri (ksba_name_t @var{name}, int @var{idx})
 Convenience function to return names representing an URI.  Caller
 must free the returned value.  Note that this function should not be
 used to enumerate the names.
@@ -801,7 +827,7 @@ Here is an example on how you can use this function to enumerate all
 
 @example
 void
-print_names (KsbaName name)
+print_names (ksba_name_t name)
 @{
   int idx;
   const char *s;
@@ -843,72 +869,32 @@ to access optional attributes of a certificate you get an appropriate error
 message.  Some error values have specific meanings if returned by a specific
 function.  Such cases are described in the documentation of those functions.
 
-@menu
-* Error values::                A list of all error values used.
-* Error strings::               How to get a descriptive string from a value.
-@end menu
-
-
-@node Error values
-@section Error values
+All error codes are defined by the library @code{libgpg-error}.  See
+there for ways to check the error values and print descriptive
+strings.  Please be aware that you can't check directly against an
+error code but have to do it like this:
 
-@deftp {Data type} {enum KsbaError}
-The @code{KsbaError} type specifies the set of all error values that are used
-by `KSBA'.  Except for the EOF and No_Error cases an application should always
-use the constants.  Possible values are:
-
-@table @code
-@item KSBA_EOF
-This value indicates the end of a list, buffer or file and is defined to have
-the value @code{-1}.
-
-@item KSBA_No_Error
-This value indicates success.  The value of this error is @code{0}.
-
-@item KSBA_General_Error
-This value means that something went wrong, but either there is not
-enough information about the problem to return a more useful error
-value, or there is no seperate error value for this type of problem.
-
-@item KSBA_Out_Of_Core
-This value means that an out-of-memory condition occured.  This might be a
-transient error and the application should not assume that it is not anymore
-poosible to allocate memory.
-
-@item KSBA_Invalid_Value
-This value means that some user provided data was out of range.  This
-can also refer to objects.  In most cases this indicates a bug.
-
-@item KSBA_Not_Implemented
-This value indicates that the specific function (or operation) is not
-implemented.  This error should never happen.  It can only occur if
-you use certain values or configuration options which do not work,
-but for which we think that they should work at some later time.
-
-@item KSBA_Read_Error
-This value means that an I/O read operation failed.
-
-@item KSBA_Write_Error
-This value means that an I/O write operation failed.
-
-@item KSBA_File_Error
-This value means that a file I/O operation failed.  The value of
-@code{errno} contains the system error value.
-
-@end table
-@end deftp
+@example
+  err = ksba_foo ();
+  if (gpg_err_code (err) == GPG_ERR_EOF)
+    okay = 1;
+@end example
 
+The only exception is that success (i.e. no error) is defined to be
+@code{0}; thus you may directly test for success like:
 
+@example
+  if (!ksba_foo ())
+    okay = 1;
+@end example
 
-@node Error strings
-@section Error strings
 
-@deftypefun {const char *} ksba_strerror (@w{KSbaError @var{err}})
-The function @code{ksba_strerror} returns a pointer to a statically
-allocated string containing a description of the error with the error
-value @var{err}.  This string can be used to output a diagnostic
-message to the user.
-@end deftypefun
+@c The following table lists the error codes as used by this library.
+@c 
+@c @table @code
+@c
+@c @end table
+@c
 
 @node Component Labels
 @appendix Component Labels
index 9a4225c..c23e7c1 100644 (file)
@@ -1,3 +1,8 @@
+2004-03-17  Werner Koch  <wk@gnupg.org>
+
+       * ber-help.c (_ksba_ber_parse_tl): Check for length overflow.
+       (_ksba_ber_read_tl): Ditto.
+
 2004-03-16  Werner Koch  <wk@gnupg.org>
 
        * ocsp.c (ksba_ocsp_get_responder_id, ksba_ocsp_get_cert): New.
index c0fc821..c7c2709 100644 (file)
@@ -104,7 +104,8 @@ _ksba_ber_read_tl (ksba_reader_t reader, struct tag_info *ti)
       tag = 0;
       do
         {
-          /* fixme: check for overflow of our datatype */
+          /* We silently ignore an overflow in the tag value.  It is
+             not worth checking for it. */
           tag <<= 7;
           c = read_byte (reader);
           if (c == -1)
@@ -149,7 +150,9 @@ _ksba_ber_read_tl (ksba_reader_t reader, struct tag_info *ti)
       unsigned long len = 0;
       int count = c & 0x7f;
 
-      /* fixme: check for overflow of our length type */
+      if (count > sizeof (len) || count > sizeof (size_t))
+        return gpg_error (GPG_ERR_BAD_BER);
+
       for (; count; count--)
         {
           len <<= 8;
@@ -208,7 +211,8 @@ _ksba_ber_parse_tl (unsigned char const **buffer, size_t *size,
       tag = 0;
       do
         {
-          /* fixme: check for overflow of our datatype */
+          /* We silently ignore an overflow in the tag value.  It is
+             not worth checking for it. */
           tag <<= 7;
           if (!length)
             return premature_eof (ti);
@@ -253,7 +257,9 @@ _ksba_ber_parse_tl (unsigned char const **buffer, size_t *size,
       unsigned long len = 0;
       int count = c & 0x7f;
 
-      /* fixme: check for overflow of our length type */
+      if (count > sizeof (len) || count > sizeof (size_t))
+        return gpg_error (GPG_ERR_BAD_BER);
+
       for (; count; count--)
         {
           len <<= 8;
index e063e6e..2f3da4a 100644 (file)
@@ -40,6 +40,9 @@ static const char oidstr_crlDistributionPoints[] = "2.5.29.31";
 static const char oidstr_certificatePolicies[] = "2.5.29.32";
 static const char oidstr_authorityKeyIdentifier[] = "2.5.29.35";
 static const char oidstr_extKeyUsage[] = "2.5.29.37";
+static const char oidstr_authorityInfoAccess[] = "1.3.6.1.5.5.7.1.1";
+static const char oidstr_subjectInfoAccess[]   = "1.3.6.1.5.5.7.1.11";
+
 
 /**
  * ksba_cert_new:
@@ -1454,7 +1457,7 @@ parse_distribution_point (const unsigned char *der, size_t derlen,
    the CRL.  This is a bit encoded value with no bit set if this has
    not been specified in the cert.
 
-   The caller may pass NULL to any of the pointer argumenst if he is
+   The caller may pass NULL to any of the pointer arguments if he is
    not interested in this value.  The return values for R_DISTPOINT
    and R_ISSUER must be released bt the caller using
    ksba_name_release(). */
@@ -1683,4 +1686,159 @@ ksba_cert_get_auth_key_id (ksba_cert_t cert,
 
 
 
+/* MODE 0 := authorityInfoAccess
+        1 := subjectInfoAccess
+
+   Caller must release METHOD and LOCATIOn if the fucntion retruned
+   with success; on error bot variables will point to NULL.
+ */   
+static gpg_error_t
+get_info_access (ksba_cert_t cert, int idx, int mode,
+                 char **method, ksba_name_t *location)
+{
+  gpg_error_t err;
+  const char *oid;
+  size_t off, derlen;
+  int myidx, crit;
+
+  *method = NULL;
+  *location = NULL;
+
+  if (!cert || !cert->initialized)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  if (idx < 0)
+    return gpg_error (GPG_ERR_INV_INDEX);
+
+  for (myidx=0; !(err=ksba_cert_get_extension (cert, myidx, &oid, &crit,
+                                               &off, &derlen)); myidx++)
+    {
+      if (!strcmp (oid,(mode == 0)? oidstr_authorityInfoAccess
+                                  : oidstr_subjectInfoAccess) )
+        {
+          const unsigned char *der;
+          struct tag_info ti;
+          size_t seqlen;
+
+          der = cert->image + off;
+
+          /* What we are going to parse is:
+           *   
+           *    AuthorityInfoAccessSyntax  ::=
+           *            SEQUENCE SIZE (1..MAX) OF AccessDescription
+           *   
+           *    AccessDescription  ::=  SEQUENCE {
+           *            accessMethod          OBJECT IDENTIFIER,
+           *            accessLocation        GeneralName  }
+           */
+          err = _ksba_ber_parse_tl (&der, &derlen, &ti);
+          if (err)
+            return err;
+          if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
+                 && ti.is_constructed) )
+            return gpg_error (GPG_ERR_INV_CERT_OBJ);
+          if (ti.ndef)
+            return gpg_error (GPG_ERR_NOT_DER_ENCODED);
+          seqlen = ti.length;
+          if (seqlen > derlen)
+            return gpg_error (GPG_ERR_BAD_BER);
+
+          /* Note: an empty sequence is actually not allowed but we
+             better don't care. */
+
+          while (seqlen)
+            {
+              err = _ksba_ber_parse_tl (&der, &derlen, &ti);
+              if (err)
+                return err;
+              if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
+                     && ti.is_constructed) )
+                return gpg_error (GPG_ERR_INV_CERT_OBJ);
+              if (derlen < ti.length)
+                return gpg_error (GPG_ERR_BAD_BER);
+              if (seqlen < ti.nhdr)
+                return gpg_error (GPG_ERR_BAD_BER);
+              seqlen -= ti.nhdr;
+              if (seqlen < ti.length)
+                return gpg_error (GPG_ERR_BAD_BER); 
+
+              if (idx)
+                { /* Skip because we are not yet at the desired index. */
+                  der    += ti.length;
+                  derlen -= ti.length;
+                  seqlen -= ti.length;
+                  idx--;
+                  continue;  
+                }
+              
+              if (!ti.length)
+                return 0;  
+
+              err = _ksba_ber_parse_tl (&der, &derlen, &ti);
+              if (err)
+                return err;
+
+              if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
+                     && !ti.is_constructed))
+                return gpg_error (GPG_ERR_INV_CERT_OBJ);
+              if (ti.ndef)
+                return gpg_error (GPG_ERR_NOT_DER_ENCODED);
+              if (derlen < ti.length)
+                return gpg_error (GPG_ERR_BAD_BER);
+
+              *method = ksba_oid_to_str (der, ti.length);
+              if (!*method)
+                return gpg_error (GPG_ERR_ENOMEM);
+              der       += ti.length;
+              derlen    -= ti.length;
+
+              err = _ksba_name_new_from_der (location, der, derlen);
+              if (err)
+                {
+                  ksba_free (*method);
+                  *method = NULL;
+                  return err;
+                }
+              return 0;
+            }
+        }
+    }
+
+  return err;
+}
+
+
+/* Return the authorityInfoAccess attributes. IDX should be iterated
+   starting from 0 until the function returns -1.  R_METHOD returns an
+   allocated string with the OID of one item and R_LOCATION return the
+   GeneralName for that OID.  The return values for R_METHOD and
+   R_LOCATION must be released by the caller unless the function
+   returned an error; the function will however make sure that
+   R_METHOD and R_LOCATION will point to NULL if the function retruns
+   an error.  See RFC 2459, section 4.2.2.1 */
+gpg_error_t
+ksba_cert_get_authority_info_access (ksba_cert_t cert, int idx,
+                                     char **r_method, ksba_name_t *r_location)
+{
+  if (!r_method || !r_location)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  return get_info_access (cert, idx, 0, r_method, r_location);
+}
+
+/* Return the subjectInfoAccess attributes. IDX should be iterated
+   starting from 0 until the function returns -1.  R_METHOD returns an
+   allocated string with the OID of one item and R_LOCATION return the
+   GeneralName for that OID.  The return values for R_METHOD and
+   R_LOCATION must be released by the caller unless the function
+   returned an error; the function will however make sure that
+   R_METHOD and R_LOCATION will point to NULL if the function retruns
+   an error.  See RFC 2459, section 4.2.2.2 */
+gpg_error_t
+ksba_cert_get_subject_info_access (ksba_cert_t cert, int idx,
+                                   char **r_method, ksba_name_t *r_location)
+{
+  if (!r_method || !r_location)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  return get_info_access (cert, idx, 1, r_method, r_location);
+}
+
 
index ebfacbb..7a761c3 100644 (file)
@@ -292,6 +292,12 @@ gpg_error_t ksba_cert_get_auth_key_id (ksba_cert_t cert,
                                        ksba_sexp_t *r_keyid,
                                        ksba_name_t *r_name,
                                        ksba_sexp_t *r_serial);
+gpg_error_t ksba_cert_get_authority_info_access (ksba_cert_t cert, int idx,
+                                                 char **r_method,
+                                                 ksba_name_t *r_location);
+gpg_error_t ksba_cert_get_subject_info_access (ksba_cert_t cert, int idx,
+                                               char **r_method,
+                                               ksba_name_t *r_location);
 
 
 /*-- cms.c --*/
index 10f5f55..ca815ad 100644 (file)
@@ -35,6 +35,7 @@ KSBA_0.9 {
     ksba_cert_get_subject; ksba_cert_get_validity; ksba_cert_hash;
     ksba_cert_init_from_mem; ksba_cert_is_ca; ksba_cert_new;
     ksba_cert_read_der; ksba_cert_ref; ksba_cert_release;
+    ksba_cert_get_authority_info_access; ksba_cert_get_subject_info_access;
 
     ksba_certreq_add_subject; ksba_certreq_build; ksba_certreq_new;
     ksba_certreq_release; ksba_certreq_set_hash_function; 
index 301769b..0d2120c 100644 (file)
@@ -1,3 +1,11 @@
+2004-03-23  Werner Koch  <wk@gnupg.org>
+
+       * cert-basic.c (print_oid_and_desc): New.
+       (list_extensions): Print info_access.
+       (print_names): Hack to optionally indent the first line too.
+       (print_oid_list): New.
+       (list_extensions): Use it.
+
 2004-03-16  Werner Koch  <wk@gnupg.org>
 
        * cert-basic.c (one_file, get_oid_desc, list_extensions): Print a
index 45545e3..e2ed10e 100644 (file)
@@ -48,7 +48,7 @@ LDADD = ../src/libksba.la @GPG_ERROR_LIBS@ -lgcrypt
 
 
 # Build the OID table: Note that the binary includes data from an
-# other rpogram and we may not be allowed to sdistribute this.  This
+# another program and we may not be allowed to distribute this.  This
 # ain't no problem as the programs using this generated data are not
 # installed and thus not distributed.
 oidtranstbl.h: Makefile mkoidtbl.awk 
@@ -57,4 +57,3 @@ oidtranstbl.h: Makefile mkoidtbl.awk
           if test -f $$i/dumpasn1.cfg; then f=$$i/dumpasn1.cfg; break; fi; \
         done; $(AWK) -f $(srcdir)/mkoidtbl.awk $$f >$@
 
-
index eeb2232..9aa6688 100644 (file)
@@ -130,11 +130,16 @@ print_dn (char *p)
     printf ("`%s'", p);
 }
 
+
 static void
 print_names (int indent, ksba_name_t name)
 {
   int idx;
   const char *s;
+  int indent_all;
+
+  if ((indent_all = (indent < 0)))
+    indent = - indent;
 
   if (!name)
     {
@@ -145,7 +150,7 @@ print_names (int indent, ksba_name_t name)
   for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
     {
       char *p = ksba_name_get_uri (name, idx);
-      printf ("%*s%s\n", idx?indent:0, "", p?p:s);
+      printf ("%*s%s\n", idx||indent_all?indent:0, "", p?p:s);
       xfree (p);
     }
 }
@@ -167,6 +172,52 @@ get_oid_desc (const char *oid)
 
 
 static void
+print_oid_and_desc (const char *oid, int with_lf)
+{
+  const char *s = get_oid_desc (oid);
+  printf ("%s%s%s%s",
+          oid, s?" (":"", s?s:"", s?")":"");
+  if (with_lf)
+    putchar ('\n');
+}
+
+
+static void
+print_oid_list (int indent, char *list)
+{
+  char *lf;
+  int indent_all, c;
+  size_t n;
+
+  if ((indent_all = (indent < 0)))
+    indent = - indent;
+
+  while (*list)
+    {
+      printf ("%*s", indent_all?indent:0, "");
+      indent_all = 1;
+      
+      if (!(lf = strchr (list, '\n')))
+        lf = list + strlen (list);
+
+      n = strspn (list, "0123456789.");
+      c = list[n];
+      list[n] = 0;
+      print_oid_and_desc (list, 0);
+      list[n] = c;
+
+      c = *lf;
+      *lf = 0;
+      printf ("  %s\n", list+n);
+      *lf = c;
+      list = *lf? (lf+1):lf;
+    }
+}
+
+          
+
+
+static void
 list_extensions (ksba_cert_t cert)
 {
   gpg_error_t err;
@@ -194,16 +245,16 @@ list_extensions (ksba_cert_t cert)
       errorcount++;
     }
 
-  /* authorithyKeyIdentifier */
+  /* authorityKeyIdentifier */
   err = ksba_cert_get_auth_key_id (cert, NULL, &name1, &serial);
   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
     {
-      fputs ("AuthorithyKeyIdentifier: ", stdout);
+      fputs ("AuthorityKeyIdentifier: ", stdout);
       if (gpg_err_code (err) == GPG_ERR_NO_DATA)
         fputs ("none", stdout);
       else
         {
-          print_names (25, name1);
+          print_names (24, name1);
           ksba_name_release (name1);
           fputs ("                 serial: ", stdout);
           print_sexp (serial);
@@ -271,13 +322,8 @@ list_extensions (ksba_cert_t cert)
     } 
   else
     {
-      /* for display purposes we replace the linefeeds by commas */
-      for (p=string; *p; p++)
-        {
-          if (*p == '\n')
-            *p = ',';
-        }
-      printf ("ExtKeyUsages: %s\n", string);
+      fputs ("ExtKeyUsages: ", stdout);
+      print_oid_list (14, string);
       xfree (string);
     }
 
@@ -299,7 +345,8 @@ list_extensions (ksba_cert_t cert)
           if (*p == '\n')
             *p = ',';
         }
-      printf ("CertificatePolicies: %s\n", string);
+      fputs ("CertificatePolicies: ", stdout);
+      print_oid_list (21, string);
       xfree (string);
     }
 
@@ -340,6 +387,44 @@ list_extensions (ksba_cert_t cert)
       errorcount++;
     } 
 
+  /* authorityInfoAccess. */
+  for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx,
+                                                         &string, &name1))
+       ; idx++)
+    {
+      fputs ("authorityInfoAccess: ", stdout);
+      print_oid_and_desc (string, 1);
+      print_names (-21, name1);
+      ksba_name_release (name1);
+      ksba_free (string);
+    }
+  if (err && gpg_err_code (err) != GPG_ERR_EOF)
+    { 
+      fprintf (stderr, "%s:%d: "
+               "ksba_cert_get_authority_info_access failed: %s\n", 
+               __FILE__, __LINE__, gpg_strerror (err));
+      errorcount++;
+    } 
+
+  /* subjectInfoAccess. */
+  for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx,
+                                                       &string, &name1))
+       ; idx++)
+    {
+      fputs ("subjectInfoAccess: ", stdout);
+      print_oid_and_desc (string, 1);
+      print_names (-19, name1);
+      ksba_name_release (name1);
+      ksba_free (string);
+    }
+  if (err && gpg_err_code (err) != GPG_ERR_EOF)
+    { 
+      fprintf (stderr, "%s:%d: "
+               "ksba_cert_get_subject_info_access failed: %s\n", 
+               __FILE__, __LINE__, gpg_strerror (err));
+      errorcount++;
+    } 
+
 }
 
 
@@ -493,7 +578,7 @@ one_file (const char *fname)
     fail_if_err (err);
 
   err = ksba_cert_read_der (cert, r);
-  if (gpg_err_code (err) != GPG_ERR_EOF)
+  if (err && gpg_err_code (err) != GPG_ERR_EOF)
     {
       fprintf (stderr, "%s:%d: expected EOF but got: %s\n", 
                __FILE__, __LINE__, gpg_strerror (err));