extensions.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
00003  *
00004  * Author: Nikos Mavrogiannopoulos
00005  *
00006  * This file is part of GNUTLS.
00007  *
00008  * The GNUTLS library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation; either version 2.1 of
00011  * the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00021  * USA
00022  *
00023  */
00024 
00025 /* Functions that relate to the X.509 extension parsing.
00026  */
00027 
00028 #include <gnutls_int.h>
00029 #include <gnutls_errors.h>
00030 #include <gnutls_global.h>
00031 #include <mpi.h>
00032 #include <libtasn1.h>
00033 #include <common.h>
00034 #include <x509.h>
00035 #include <extensions.h>
00036 #include <gnutls_datum.h>
00037 
00038 /* This function will attempt to return the requested extension found in
00039  * the given X509v3 certificate. The return value is allocated and stored into
00040  * ret.
00041  *
00042  * Critical will be either 0 or 1.
00043  *
00044  * If the extension does not exist, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
00045  * be returned.
00046  */
00047 int
00048 MHD__gnutls_x509_crt_get_extension (MHD_gnutls_x509_crt_t cert,
00049                                     const char *extension_id, int indx,
00050                                     MHD_gnutls_datum_t * ret,
00051                                     unsigned int *_critical)
00052 {
00053   int k, result, len;
00054   char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
00055   char str[1024];
00056   char str_critical[10];
00057   int critical = 0;
00058   char extnID[128];
00059   MHD_gnutls_datum_t value;
00060   int indx_counter = 0;
00061 
00062   ret->data = NULL;
00063   ret->size = 0;
00064 
00065   k = 0;
00066   do
00067     {
00068       k++;
00069 
00070       snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", k);
00071 
00072       len = sizeof (str) - 1;
00073       result = MHD__asn1_read_value (cert->cert, name, str, &len);
00074 
00075       /* move to next
00076        */
00077 
00078       if (result == ASN1_ELEMENT_NOT_FOUND)
00079         {
00080           break;
00081         }
00082 
00083       do
00084         {
00085 
00086           MHD_gtls_str_cpy (name2, sizeof (name2), name);
00087           MHD_gtls_str_cat (name2, sizeof (name2), ".extnID");
00088 
00089           len = sizeof (extnID) - 1;
00090           result = MHD__asn1_read_value (cert->cert, name2, extnID, &len);
00091 
00092           if (result == ASN1_ELEMENT_NOT_FOUND)
00093             {
00094               MHD_gnutls_assert ();
00095               break;
00096             }
00097           else if (result != ASN1_SUCCESS)
00098             {
00099               MHD_gnutls_assert ();
00100               return MHD_gtls_asn2err (result);
00101             }
00102 
00103           /* Handle Extension
00104            */
00105           if (strcmp (extnID, extension_id) == 0 && indx == indx_counter++)
00106             {
00107               /* extension was found
00108                */
00109 
00110               /* read the critical status.
00111                */
00112               MHD_gtls_str_cpy (name2, sizeof (name2), name);
00113               MHD_gtls_str_cat (name2, sizeof (name2), ".critical");
00114 
00115               len = sizeof (str_critical);
00116               result =
00117                 MHD__asn1_read_value (cert->cert, name2, str_critical, &len);
00118 
00119               if (result == ASN1_ELEMENT_NOT_FOUND)
00120                 {
00121                   MHD_gnutls_assert ();
00122                   break;
00123                 }
00124               else if (result != ASN1_SUCCESS)
00125                 {
00126                   MHD_gnutls_assert ();
00127                   return MHD_gtls_asn2err (result);
00128                 }
00129 
00130               if (str_critical[0] == 'T')
00131                 critical = 1;
00132               else
00133                 critical = 0;
00134 
00135               /* read the value.
00136                */
00137               MHD_gtls_str_cpy (name2, sizeof (name2), name);
00138               MHD_gtls_str_cat (name2, sizeof (name2), ".extnValue");
00139 
00140               result =
00141                 MHD__gnutls_x509_read_value (cert->cert, name2, &value, 0);
00142               if (result < 0)
00143                 {
00144                   MHD_gnutls_assert ();
00145                   return result;
00146                 }
00147 
00148               ret->data = value.data;
00149               ret->size = value.size;
00150 
00151               if (_critical)
00152                 *_critical = critical;
00153 
00154               return 0;
00155             }
00156 
00157 
00158         }
00159       while (0);
00160     }
00161   while (1);
00162 
00163   if (result == ASN1_ELEMENT_NOT_FOUND)
00164     {
00165       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
00166     }
00167   else
00168     {
00169       MHD_gnutls_assert ();
00170       return MHD_gtls_asn2err (result);
00171     }
00172 }
00173 
00174 /* Here we only extract the KeyUsage field, from the DER encoded
00175  * extension.
00176  */
00177 int
00178 MHD__gnutls_x509_ext_extract_keyUsage (uint16_t * keyUsage,
00179                                        opaque * extnValue, int extnValueLen)
00180 {
00181   ASN1_TYPE ext = ASN1_TYPE_EMPTY;
00182   int len, result;
00183   uint8_t str[2];
00184 
00185   str[0] = str[1] = 0;
00186   *keyUsage = 0;
00187 
00188   if ((result = MHD__asn1_create_element
00189        (MHD__gnutls_get_pkix (), "PKIX1.KeyUsage", &ext)) != ASN1_SUCCESS)
00190     {
00191       MHD_gnutls_assert ();
00192       return MHD_gtls_asn2err (result);
00193     }
00194 
00195   result = MHD__asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
00196 
00197   if (result != ASN1_SUCCESS)
00198     {
00199       MHD_gnutls_assert ();
00200       MHD__asn1_delete_structure (&ext);
00201       return MHD_gtls_asn2err (result);
00202     }
00203 
00204   len = sizeof (str);
00205   result = MHD__asn1_read_value (ext, "", str, &len);
00206   if (result != ASN1_SUCCESS)
00207     {
00208       MHD_gnutls_assert ();
00209       MHD__asn1_delete_structure (&ext);
00210       return 0;
00211     }
00212 
00213   *keyUsage = str[0] | (str[1] << 8);
00214 
00215   MHD__asn1_delete_structure (&ext);
00216 
00217   return 0;
00218 }

Generated on Fri Feb 27 18:32:19 2009 for GNU libmicrohttpd by  doxygen 1.5.7.1