]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added gnutls_x509_crt_get_authority_info_access.
authorSimon Josefsson <simon@josefsson.org>
Wed, 21 Sep 2011 12:51:08 +0000 (14:51 +0200)
committerSimon Josefsson <simon@josefsson.org>
Wed, 21 Sep 2011 12:52:37 +0000 (14:52 +0200)
NEWS
doc/manpages/Makefile.am
lib/includes/gnutls/x509.h
lib/libgnutls.map
lib/pkix.asn
lib/pkix_asn1_tab.c
lib/x509/x509.c
tests/Makefile.am
tests/infoaccess.c [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index cc468b7d50cf54f403f19c88e58ed80ec173ca7f..9826af18923e8b01d4fcd56a9f16013e3a8253c6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,17 @@ GnuTLS NEWS -- History of user-visible changes.                -*- outline -*-
 Copyright (C) 2000-2011 Free Software Foundation, Inc.
 See the end for copying conditions.
 
+* Version 3.0.4 (unreleased)
+
+** libgnutls: Added gnutls_x509_crt_get_authority_info_access.
+Used to get the PKIX Authority Information Access field.
+
+** API and ABI modifications:
+gnutls_x509_crt_get_authority_info_access (x509.h): Added function.
+gnutls_info_access_what_t (x509.h): Added enum.
+GNUTLS_OID_AIA (x509.h): Added symbol.
+GNUTLS_OID_AD_OCSP (x509.h): Added symbol.
+
 * Version 3.0.3 (released 2011-09-18)
 
 ** libgnutls: Added gnutls_record_get_discarded() to return the
index aaabc4f81316e045f1de641a5734b4dd42928f6f..170e0ee7e894318b1f2e2f184b3ef2da301b66c7 100644 (file)
@@ -531,6 +531,7 @@ APIMANS += gnutls_x509_crt_list_import2.3
 APIMANS += gnutls_x509_crt_list_import.3
 APIMANS += gnutls_x509_crt_get_subject_unique_id.3
 APIMANS += gnutls_x509_crt_get_issuer_unique_id.3
+APIMANS += gnutls_x509_crt_get_authority_info_access.3
 APIMANS += gnutls_x509_crt_set_dn_by_oid.3
 APIMANS += gnutls_x509_crt_set_issuer_dn_by_oid.3
 APIMANS += gnutls_x509_crt_set_proxy_dn.3
index 67b5a1e37d2f6ae7d04a1175629c55d1618d490f..6b73f18a03936a7cdacde3b398efd0c026c0a5bd 100644 (file)
@@ -78,6 +78,9 @@ extern "C"
 #define GNUTLS_KP_IPSEC_IKE                    "1.3.6.1.5.5.7.3.17"
 #define GNUTLS_KP_ANY                          "2.5.29.37.0"
 
+#define GNUTLS_OID_AIA                         "1.3.6.1.5.5.7.1.1"
+#define GNUTLS_OID_AD_OCSP                     "1.3.6.1.5.5.7.48.1"
+
 #define GNUTLS_FSAN_SET 0
 #define GNUTLS_FSAN_APPEND 1
 
@@ -162,6 +165,31 @@ extern "C"
   int gnutls_x509_crt_get_issuer_unique_id (gnutls_x509_crt_t crt, char *buf,
                                             size_t * buf_size);
 
+  /**
+   * gnutls_info_access_what_t:
+   *
+   * Enumeration of types for the @what parameter of
+   * gnutls_x509_crt_get_authority_info_access().
+   */
+  typedef enum gnutls_info_access_what_t
+    {
+      /* get accessMethod OID */
+      GNUTLS_IA_ACCESSMETHOD_OID = 1,
+      /* get accessLocation name type */
+      GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE = 2,
+      /* use 100-108 for the generalName types, populate as needed */
+      /* get accessLocation URI value */
+      GNUTLS_IA_URI = 106,
+      /* quick-access variants that match both OID and name type. */
+      GNUTLS_IA_OCSP_URI = 10006
+    } gnutls_info_access_what_t;
+
+  int gnutls_x509_crt_get_authority_info_access (gnutls_x509_crt_t crt,
+                                                unsigned int seq,
+                                                int what,
+                                                gnutls_datum_t * data,
+                                                int *critical);
+
 #define GNUTLS_CRL_REASON_UNUSED 128
 #define GNUTLS_CRL_REASON_KEY_COMPROMISE 64
 #define GNUTLS_CRL_REASON_CA_COMPROMISE 32
index 70bc8414ca7a74d1c6d288726636c8cc4c2c81b0..b80f7bc0f88d7fc36f8e8ad712d7e598ec13eb1d 100644 (file)
@@ -717,6 +717,7 @@ GNUTLS_3_0_0 {
        gnutls_pubkey_import_ecc_raw;
        gnutls_pubkey_import_ecc_raw2;
        gnutls_record_get_discarded;
+       gnutls_x509_crt_get_authority_info_access;
 } GNUTLS_2_12;
 
 GNUTLS_PRIVATE {
index e805fb7abf46c63aa02aea0a9f33ab515af519e3..ef1937c92597f456deecd49a5197c85af1ffd427 100644 (file)
@@ -101,6 +101,15 @@ ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
 
 KeyPurposeId ::= OBJECT IDENTIFIER
 
+-- authority info access
+
+AuthorityInfoAccessSyntax  ::=
+        SEQUENCE SIZE (1..MAX) OF AccessDescription
+
+AccessDescription  ::=  SEQUENCE {
+        accessMethod          OBJECT IDENTIFIER,
+        accessLocation        GeneralName  }
+
 -- CRL number extension OID and syntax
 
 CRLNumber ::= INTEGER (0..MAX)
index d5d5cc405e09567afdb426e34e2ccf334f3a4871..c42b155b4ad6c9d71a8c464b41478c23bf3496f2 100644 (file)
@@ -92,6 +92,12 @@ const ASN1_ARRAY_TYPE pkix_asn1_tab[] = {
   { "MAX", 1074266122, "1"},
   { NULL, 2, "KeyPurposeId"},
   { "KeyPurposeId", 1073741836, NULL },
+  { "AuthorityInfoAccessSyntax", 1612709899, NULL },
+  { "MAX", 1074266122, "1"},
+  { NULL, 2, "AccessDescription"},
+  { "AccessDescription", 1610612741, NULL },
+  { "accessMethod", 1073741836, NULL },
+  { "accessLocation", 2, "GeneralName"},
   { "CRLNumber", 1611137027, NULL },
   { "0", 10, "MAX"},
   { "CertificateIssuer", 1073741826, "GeneralNames"},
index 34310721bb13bbfae651fc82722d380a03f5c49e..c3ee568940ba7a45d3f2184176f53f072b2551d3 100644 (file)
@@ -3389,3 +3389,209 @@ gnutls_x509_crt_get_issuer_unique_id (gnutls_x509_crt_t crt, char *buf,
 
   return result;
 }
+
+static int
+_gnutls_parse_aia (ASN1_TYPE src,
+                  unsigned int seq,
+                  int what,
+                  gnutls_datum_t * data)
+{
+  int len;
+  char nptr[ASN1_MAX_NAME_SIZE];
+  int result;
+  gnutls_datum_t d;
+
+  seq++;                        /* 0->1, 1->2 etc */
+  switch (what)
+    {
+    case GNUTLS_IA_ACCESSMETHOD_OID:
+      snprintf (nptr, sizeof (nptr), "?%u.accessMethod", seq);
+      break;
+
+    case GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE:
+      snprintf (nptr, sizeof (nptr), "?%u.accessLocation", seq);
+      break;
+
+    case GNUTLS_IA_OCSP_URI:
+      {
+       char *tmpoid[20];
+       snprintf (nptr, sizeof (nptr), "?%u.accessMethod", seq);
+       len = sizeof (tmpoid);
+       result = asn1_read_value (src, nptr, tmpoid, &len);
+       if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
+         return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       if (result != ASN1_SUCCESS)
+         {
+           gnutls_assert ();
+           return _gnutls_asn2err (result);
+         }
+       if (len != sizeof (GNUTLS_OID_AD_OCSP) ||
+           memcmp (tmpoid, GNUTLS_OID_AD_OCSP, len) != 0)
+         return GNUTLS_E_UNKNOWN_ALGORITHM;
+      }
+      /* fall through */
+
+      case GNUTLS_IA_URI:
+       snprintf (nptr, sizeof (nptr),
+                 "?%u.accessLocation.uniformResourceIdentifier", seq);
+       break;
+
+    default:
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  len = 0;
+  result = asn1_read_value (src, nptr, NULL, &len);
+  if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
+    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+  if (result != ASN1_MEM_ERROR)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+  d.size = len;
+  d.data = gnutls_malloc (d.size);
+  if (d.data == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+  result = asn1_read_value (src, nptr, d.data, &len);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      gnutls_free (d.data);
+      return _gnutls_asn2err (result);
+    }
+
+  if (data)
+    {
+      data->data = d.data;
+      data->size = d.size;
+    }
+  else
+    gnutls_free (d.data);
+
+  return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_x509_crt_get_authority_info_access:
+ * @crt: Holds the certificate
+ * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
+ * @what: what data to get, a #gnutls_info_access_what_t type.
+ * @data: output data to be freed with gnutls_free().
+ * @critical: pointer to output integer that is set to non-0 if the extension is marked as critical (may be %NULL)
+ *
+ * This function extracts the Authority Information Access (AIA)
+ * extension, see RFC 5280 section 4.2.2.1 for more information.  The
+ * AIA extension holds a sequence of AccessDescription (AD) data:
+ *
+ * <informalexample><programlisting>
+ * AuthorityInfoAccessSyntax  ::=
+ *         SEQUENCE SIZE (1..MAX) OF AccessDescription
+ *
+ * AccessDescription  ::=  SEQUENCE {
+ *         accessMethod          OBJECT IDENTIFIER,
+ *         accessLocation        GeneralName  }
+ * </programlisting></informalexample>
+ *
+ * The @seq input parameter is used to indicate which member of the
+ * sequence the caller is interested in.  The first member is 0, the
+ * second member 1 and so on.  When the @seq value is out of bounds,
+ * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
+ *
+ * The type of data returned in @data is specified via @what which
+ * should be #gnutls_info_access_what_t values.
+ *
+ * If @what is %GNUTLS_IA_ACCESSMETHOD_OID then @data will hold the
+ * accessMethod OID (e.g., "1.3.6.1.5.5.7.48.1" for id-ad-ocsp meaning
+ * OCSP).
+ *
+ * If @what is %GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, @data will
+ * hold the accessLocation GeneralName type (e.g.,
+ * "uniformResourceIdentifier").
+ *
+ * If @what is %GNUTLS_IA_URI, @data will hold the accessLocation URI
+ * data.  Requesting this @what value leads to an error if the
+ * accessLocation is not of the "uniformResourceIdentifier" type.
+ *
+ * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
+ * Requesting this @what value leads to an error if the accessMethod
+ * is not OSCP or accessLocation is not of the
+ * "uniformResourceIdentifier" type.
+ *
+ * More @what values may be allocated in the future as needed.
+ *
+ * If @data is NULL, the function does the same without storing the
+ * output data, that is, it will set @critical and do error checking
+ * as usual.
+ *
+ * The value of the critical flag is returned in *@critical.  Supply a
+ * NULL @critical if you want the function to make sure the extension
+ * is non-critical, as required by RFC 5280.
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, %GNUTLS_E_INVALID_REQUEST on
+ * invalid @crt, %GNUTLS_E_CONSTRAINT_ERROR if the extension is
+ * incorrectly marked as critical (use a non-NULL @critical to
+ * override), %GNUTLS_E_UNKNOWN_ALGORITHM if the requested OID does
+ * not match (e.g., when using %GNUTLS_IA_OCSP_URI), otherwise a
+ * negative error code.
+ **/
+int
+gnutls_x509_crt_get_authority_info_access (gnutls_x509_crt_t crt,
+                                          unsigned int seq,
+                                          int what,
+                                          gnutls_datum_t * data,
+                                          int *critical)
+{
+  int ret;
+  gnutls_datum_t aia;
+  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
+
+  if (crt == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  if ((ret = _gnutls_x509_crt_get_extension (crt, GNUTLS_OID_AIA, 0, &aia,
+                                            critical)) < 0)
+    return ret;
+
+  if (aia.size == 0 || aia.data == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+    }
+
+  if (critical && *critical)
+    return GNUTLS_E_CONSTRAINT_ERROR;
+
+  ret = asn1_create_element (_gnutls_get_pkix (),
+                            "PKIX1.AuthorityInfoAccessSyntax", &c2);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      _gnutls_free_datum (&aia);
+      return _gnutls_asn2err (ret);
+    }
+
+  ret = asn1_der_decoding (&c2, aia.data, aia.size, NULL);
+  /* asn1_print_structure (stdout, c2, "", ASN1_PRINT_ALL); */
+  _gnutls_free_datum (&aia);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&c2);
+      return _gnutls_asn2err (ret);
+    }
+
+  ret = _gnutls_parse_aia (c2, seq, what, data);
+  asn1_delete_structure (&c2);
+  if (ret < 0)
+    gnutls_assert ();
+
+  return ret;
+}
index 40ab5b56035e2b7e01d628a13608c7536339828c..63ae6653c9238e42d129b4c0fb89b5e708c7985f 100644 (file)
@@ -64,7 +64,7 @@ ctests = simple gc set_pkcs12_cred certder certuniqueid mpi           \
        init_roundtrip pkcs12_s2k_pem dn2 mini-eagain                   \
        nul-in-x509-names x509_altname pkcs12_encode mini-x509          \
        mini-x509-rehandshake rng-fork mini-eagain-dtls cipher-test     \
-       x509cert x509cert-tl #gendh
+       x509cert x509cert-tl infoaccess #gendh
 
 if ENABLE_OPENSSL
 ctests +=  openssl
diff --git a/tests/infoaccess.c b/tests/infoaccess.c
new file mode 100644 (file)
index 0000000..242b334
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2011 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/x509.h>
+
+#include "utils.h"
+
+static char cert_with_aia_data[] =
+  "-----BEGIN CERTIFICATE-----\n"
+  "MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC\n"
+  "TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0\n"
+  "aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0\n"
+  "aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz\n"
+  "MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw\n"
+  "IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR\n"
+  "dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG\n"
+  "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp\n"
+  "li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D\n"
+  "rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ\n"
+  "WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug\n"
+  "F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU\n"
+  "xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC\n"
+  "Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv\n"
+  "dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw\n"
+  "ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl\n"
+  "IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh\n"
+  "c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy\n"
+  "ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh\n"
+  "Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI\n"
+  "KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T\n"
+  "KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq\n"
+  "y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p\n"
+  "dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD\n"
+  "VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL\n"
+  "MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk\n"
+  "fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8\n"
+  "7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R\n"
+  "cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y\n"
+  "mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW\n"
+  "xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK\n"
+  "SnQ2+Q==\n"
+  "-----END CERTIFICATE-----\n";
+
+const gnutls_datum_t cert_with_aia = {
+  cert_with_aia_data, sizeof (cert_with_aia_data)
+};
+
+void
+doit (void)
+{
+  gnutls_x509_crt_t crt;
+  int ret;
+  gnutls_datum_t data;
+  int critical;
+
+  ret = gnutls_global_init ();
+  if (ret < 0)
+    {
+      fail ("gnutls_global_init\n");
+      exit (1);
+    }
+
+  ret = gnutls_x509_crt_init (&crt);
+  if (ret != 0)
+    {
+      fail ("gnutls_x509_crt_init\n");
+      exit (1);
+    }
+
+  ret = gnutls_x509_crt_import (crt, &cert_with_aia, GNUTLS_X509_FMT_PEM);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_import\n");
+      exit (1);
+    }
+
+  /* test null input */
+  ret = gnutls_x509_crt_get_authority_info_access (NULL, 0, 0, NULL, NULL);
+  if (ret != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_x509_crt_get_authority_info_access null input\n");
+      exit (1);
+    }
+
+  /* test unused enum */
+  ret = gnutls_x509_crt_get_authority_info_access (crt, 0, 44, NULL, NULL);
+  if (ret != GNUTLS_E_INVALID_REQUEST)
+    {
+      fail ("gnutls_x509_crt_get_authority_info_access insane input\n");
+      exit (1);
+    }
+
+  /* test basic query with null output */
+  ret = gnutls_x509_crt_get_authority_info_access
+    (crt, 0, GNUTLS_IA_ACCESSMETHOD_OID, NULL, NULL);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_get_authority_info_access "
+           "GNUTLS_IA_ACCESSMETHOD_OID null output critical\n");
+      exit (1);
+    }
+
+  /* test same as previous but also check that critical flag is
+     correct */
+  ret = gnutls_x509_crt_get_authority_info_access
+    (crt, 0, GNUTLS_IA_ACCESSMETHOD_OID, NULL, &critical);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_get_authority_info_access "
+           "GNUTLS_IA_ACCESSMETHOD_OID null output\n");
+      exit (1);
+    }
+
+  if (critical != 0)
+    {
+      fail ("gnutls_x509_crt_get_authority_info_access "
+           "critical failed: %d\n", critical);
+      exit (1);
+    }
+
+  /* basic query of another type */
+  ret = gnutls_x509_crt_get_authority_info_access
+    (crt, 0, GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, NULL, NULL);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_get_authority_info_access "
+           "GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE null output\n");
+      exit (1);
+    }
+
+  /* basic query of another type, with out-of-bound sequence */
+  ret = gnutls_x509_crt_get_authority_info_access
+    (crt, 1, GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, NULL, NULL);
+  if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+    {
+      fail ("gnutls_x509_crt_get_authority_info_access "
+           "GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE out-of-bounds\n");
+      exit (1);
+    }
+
+  /* basic query and check output value */
+  ret = gnutls_x509_crt_get_authority_info_access
+    (crt, 0, GNUTLS_IA_ACCESSMETHOD_OID, &data, NULL);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_get_authority_info_access "
+           "GNUTLS_IA_ACCESSMETHOD_OID\n");
+      exit (1);
+    }
+
+  if (memcmp ("1.3.6.1.5.5.7.48.1", data.data, data.size) != 0)
+    {
+      fail ("memcmp OCSP OID failed\n");
+      exit (1);
+    }
+  gnutls_free (data.data);
+
+  /* basic query of another type and check output value */
+  ret = gnutls_x509_crt_get_authority_info_access
+    (crt, 0, GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, &data, NULL);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_get_authority_info_access "
+           "GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE\n");
+      exit (1);
+    }
+
+  if (memcmp ("uniformResourceIdentifier", data.data, data.size) != 0)
+    {
+      fail ("memcmp URI failed\n");
+      exit (1);
+    }
+  gnutls_free (data.data);
+
+  /* specific query */
+  ret = gnutls_x509_crt_get_authority_info_access
+    (crt, 0, GNUTLS_IA_URI, &data, NULL);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_get_authority_info_access GNUTLS_IA_URI\n");
+      exit (1);
+    }
+
+  if (memcmp ("https://ocsp.quovadisoffshore.com", data.data, data.size) != 0)
+    {
+      fail ("memcmp URI value failed\n");
+      exit (1);
+    }
+  gnutls_free (data.data);
+
+  /* even more specific query */
+  ret = gnutls_x509_crt_get_authority_info_access
+    (crt, 0, GNUTLS_IA_OCSP_URI, &data, NULL);
+  printf ("ret %d\n", ret);
+  if (ret < 0)
+    {
+      fail ("gnutls_x509_crt_get_authority_info_access GNUTLS_IA_OCSP_URI\n");
+      exit (1);
+    }
+
+  if (memcmp ("https://ocsp.quovadisoffshore.com", data.data, data.size) != 0)
+    {
+      fail ("memcmp URI value failed\n");
+      exit (1);
+    }
+  gnutls_free (data.data);
+
+  gnutls_global_deinit ();
+
+}