x509.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
00003  * Author: Nikos Mavrogiannopoulos, Simon Josefsson, Howard Chu
00004  *
00005  * This file is part of GNUTLS.
00006  *
00007  * The GNUTLS library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00020  * USA
00021  *
00022  */
00023 
00024 /* Functions on X.509 Certificate parsing
00025  */
00026 
00027 #include <gnutls_int.h>
00028 #include <gnutls_datum.h>
00029 #include <gnutls_global.h>
00030 #include <gnutls_errors.h>
00031 #include <common.h>
00032 #include <gnutls_x509.h>
00033 #include <x509_b64.h>
00034 #include <x509.h>
00035 #include <extensions.h>
00036 #include <libtasn1.h>
00037 #include <mpi.h>
00038 #include <privkey.h>
00039 
00049 int
00050 MHD_gnutls_x509_crt_init (MHD_gnutls_x509_crt_t * cert)
00051 {
00052   MHD_gnutls_x509_crt_t tmp =
00053     MHD_gnutls_calloc (1, sizeof (MHD_gnutls_x509_crt_int));
00054   int result;
00055 
00056   if (!tmp)
00057     return GNUTLS_E_MEMORY_ERROR;
00058 
00059   result = MHD__asn1_create_element (MHD__gnutls_get_pkix (),
00060                                      "PKIX1.Certificate", &tmp->cert);
00061   if (result != ASN1_SUCCESS)
00062     {
00063       MHD_gnutls_assert ();
00064       MHD_gnutls_free (tmp);
00065       return MHD_gtls_asn2err (result);
00066     }
00067 
00068   *cert = tmp;
00069 
00070   return 0;                     /* success */
00071 }
00072 
00080 void
00081 MHD_gnutls_x509_crt_deinit (MHD_gnutls_x509_crt_t cert)
00082 {
00083   if (!cert)
00084     return;
00085 
00086   if (cert->cert)
00087     MHD__asn1_delete_structure (&cert->cert);
00088 
00089   MHD_gnutls_free (cert);
00090 }
00091 
00107 int
00108 MHD_gnutls_x509_crt_import (MHD_gnutls_x509_crt_t cert,
00109                             const MHD_gnutls_datum_t * data,
00110                             MHD_gnutls_x509_crt_fmt_t format)
00111 {
00112   int result = 0, need_free = 0;
00113   MHD_gnutls_datum_t _data;
00114   opaque *signature = NULL;
00115 
00116   if (cert == NULL)
00117     {
00118       MHD_gnutls_assert ();
00119       return GNUTLS_E_INVALID_REQUEST;
00120     }
00121 
00122   _data.data = data->data;
00123   _data.size = data->size;
00124 
00125   /* If the Certificate is in PEM format then decode it
00126    */
00127   if (format == GNUTLS_X509_FMT_PEM)
00128     {
00129       opaque *out;
00130 
00131       /* Try the first header */
00132       result =
00133         MHD__gnutls_fbase64_decode (PEM_X509_CERT2, data->data, data->size,
00134                                     &out);
00135 
00136       if (result <= 0)
00137         {
00138           /* try for the second header */
00139           result = MHD__gnutls_fbase64_decode (PEM_X509_CERT, data->data,
00140                                                data->size, &out);
00141 
00142           if (result <= 0)
00143             {
00144               if (result == 0)
00145                 result = GNUTLS_E_INTERNAL_ERROR;
00146               MHD_gnutls_assert ();
00147               return result;
00148             }
00149         }
00150 
00151       _data.data = out;
00152       _data.size = result;
00153 
00154       need_free = 1;
00155     }
00156 
00157   result = MHD__asn1_der_decoding (&cert->cert, _data.data, _data.size, NULL);
00158   if (result != ASN1_SUCCESS)
00159     {
00160       result = MHD_gtls_asn2err (result);
00161       MHD_gnutls_assert ();
00162       goto cleanup;
00163     }
00164 
00165   /* Since we do not want to disable any extension
00166    */
00167   cert->use_extensions = 1;
00168   if (need_free)
00169     MHD__gnutls_free_datum (&_data);
00170 
00171   return 0;
00172 
00173 cleanup:MHD_gnutls_free (signature);
00174   if (need_free)
00175     MHD__gnutls_free_datum (&_data);
00176   return result;
00177 }
00178 
00188 int
00189 MHD_gnutls_x509_crt_get_version (MHD_gnutls_x509_crt_t cert)
00190 {
00191   opaque version[5];
00192   int len, result;
00193 
00194   if (cert == NULL)
00195     {
00196       MHD_gnutls_assert ();
00197       return GNUTLS_E_INVALID_REQUEST;
00198     }
00199 
00200   len = sizeof (version);
00201   if ((result =
00202        MHD__asn1_read_value (cert->cert, "tbsCertificate.version", version,
00203                              &len)) != ASN1_SUCCESS)
00204     {
00205 
00206       if (result == ASN1_ELEMENT_NOT_FOUND)
00207         return 1;               /* the DEFAULT version */
00208       MHD_gnutls_assert ();
00209       return MHD_gtls_asn2err (result);
00210     }
00211 
00212   return (int) version[0] + 1;
00213 }
00214 
00232 int
00233 MHD_gnutls_x509_crt_get_pk_algorithm (MHD_gnutls_x509_crt_t cert,
00234                                       unsigned int *bits)
00235 {
00236   int result;
00237 
00238   if (cert == NULL)
00239     {
00240       MHD_gnutls_assert ();
00241       return GNUTLS_E_INVALID_REQUEST;
00242     }
00243 
00244   result = MHD__gnutls_x509_get_pk_algorithm (cert->cert,
00245                                               "tbsCertificate.subjectPublicKeyInfo",
00246                                               bits);
00247 
00248   if (result < 0)
00249     {
00250       MHD_gnutls_assert ();
00251       return result;
00252     }
00253 
00254   return result;
00255 
00256 }
00257 
00258 inline static int
00259 is_type_printable (int type)
00260 {
00261   if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME || type
00262       == GNUTLS_SAN_URI)
00263     return 1;
00264   else
00265     return 0;
00266 }
00267 
00287 int
00288 MHD_gnutls_x509_crt_get_key_usage (MHD_gnutls_x509_crt_t cert,
00289                                    unsigned int *key_usage,
00290                                    unsigned int *critical)
00291 {
00292   int result;
00293   MHD_gnutls_datum_t keyUsage;
00294   uint16_t _usage;
00295 
00296   if (cert == NULL)
00297     {
00298       MHD_gnutls_assert ();
00299       return GNUTLS_E_INVALID_REQUEST;
00300     }
00301 
00302   if ((result =
00303        MHD__gnutls_x509_crt_get_extension (cert, "2.5.29.15", 0, &keyUsage,
00304                                            critical)) < 0)
00305     {
00306       return result;
00307     }
00308 
00309   if (keyUsage.size == 0 || keyUsage.data == NULL)
00310     {
00311       MHD_gnutls_assert ();
00312       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
00313     }
00314 
00315   result = MHD__gnutls_x509_ext_extract_keyUsage (&_usage, keyUsage.data,
00316                                                   keyUsage.size);
00317   MHD__gnutls_free_datum (&keyUsage);
00318 
00319   *key_usage = _usage;
00320 
00321   if (result < 0)
00322     {
00323       MHD_gnutls_assert ();
00324       return result;
00325     }
00326 
00327   return 0;
00328 }
00329 
00330 
00351 int
00352 MHD_gnutls_x509_crt_export (MHD_gnutls_x509_crt_t cert,
00353                             MHD_gnutls_x509_crt_fmt_t format,
00354                             void *output_data, size_t * output_data_size)
00355 {
00356   if (cert == NULL)
00357     {
00358       MHD_gnutls_assert ();
00359       return GNUTLS_E_INVALID_REQUEST;
00360     }
00361 
00362   return MHD__gnutls_x509_export_int (cert->cert, format, "CERTIFICATE",
00363                                       output_data, output_data_size);
00364 }

Generated on Tue May 19 23:21:08 2009 for GNU libmicrohttpd by  doxygen 1.5.8