gnutls_mpi.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001, 2002, 2003, 2004, 2005 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 /* Here lie everything that has to do with large numbers, libgcrypt and
00026  * other stuff that didn't fit anywhere else.
00027  */
00028 
00029 #include <gnutls_int.h>
00030 #include <libtasn1.h>
00031 #include <gnutls_errors.h>
00032 #include <gnutls_num.h>
00033 
00034 /* Functions that refer to the libgcrypt library.
00035  */
00036 
00037 void
00038 MHD_gtls_mpi_release (mpi_t * x)
00039 {
00040   if (*x == NULL)
00041     return;
00042   gcry_mpi_release (*x);
00043   *x = NULL;
00044 }
00045 
00046 /* returns zero on success
00047  */
00048 int
00049 MHD_gtls_mpi_scan (mpi_t * ret_mpi, const opaque * buffer, size_t * nbytes)
00050 {
00051   int ret;
00052 
00053   ret = gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, buffer, *nbytes, nbytes);
00054   if (ret)
00055     return GNUTLS_E_MPI_SCAN_FAILED;
00056 
00057   return 0;
00058 }
00059 
00060 /* returns zero on success. Fails if the number is zero.
00061  */
00062 int
00063 MHD_gtls_mpi_scan_nz (mpi_t * ret_mpi, const opaque * buffer, size_t * nbytes)
00064 {
00065   int ret;
00066 
00067   ret = gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, buffer, *nbytes, nbytes);
00068   if (ret)
00069     return GNUTLS_E_MPI_SCAN_FAILED;
00070 
00071   /* MPIs with 0 bits are illegal
00072    */
00073   if (MHD__gnutls_mpi_get_nbits (*ret_mpi) == 0)
00074     {
00075       MHD_gtls_mpi_release (ret_mpi);
00076       return GNUTLS_E_MPI_SCAN_FAILED;
00077     }
00078 
00079   return 0;
00080 }
00081 
00082 int
00083 MHD_gtls_mpi_print (void *buffer, size_t * nbytes, const mpi_t a)
00084 {
00085   int ret;
00086 
00087   if (nbytes == NULL || a == NULL)
00088     return GNUTLS_E_INVALID_REQUEST;
00089 
00090   ret = gcry_mpi_print (GCRYMPI_FMT_USG, buffer, *nbytes, nbytes, a);
00091   if (!ret)
00092     return 0;
00093 
00094   return GNUTLS_E_MPI_PRINT_FAILED;
00095 }
00096 
00097 /* Always has the first bit zero */
00098 static int
00099 MHD_gtls_mpi_print_lz (void *buffer, size_t * nbytes, const mpi_t a)
00100 {
00101   int ret;
00102 
00103   if (nbytes == NULL || a == NULL)
00104     return GNUTLS_E_INVALID_REQUEST;
00105 
00106   ret = gcry_mpi_print (GCRYMPI_FMT_STD, buffer, *nbytes, nbytes, a);
00107   if (!ret)
00108     return 0;
00109 
00110   return GNUTLS_E_MPI_PRINT_FAILED;
00111 }
00112 
00113 /* Always has the first bit zero */
00114 int
00115 MHD_gtls_mpi_dprint_lz (MHD_gnutls_datum_t * dest, const mpi_t a)
00116 {
00117   int ret;
00118   opaque *buf = NULL;
00119   size_t bytes = 0;
00120 
00121   if (dest == NULL || a == NULL)
00122     return GNUTLS_E_INVALID_REQUEST;
00123 
00124   gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &bytes, a);
00125 
00126   if (bytes != 0)
00127     buf = MHD_gnutls_malloc (bytes);
00128   if (buf == NULL)
00129     return GNUTLS_E_MEMORY_ERROR;
00130 
00131   ret = gcry_mpi_print (GCRYMPI_FMT_STD, buf, bytes, &bytes, a);
00132   if (!ret)
00133     {
00134       dest->data = buf;
00135       dest->size = bytes;
00136       return 0;
00137     }
00138 
00139   MHD_gnutls_free (buf);
00140   return GNUTLS_E_MPI_PRINT_FAILED;
00141 }
00142 
00143 int
00144 MHD_gtls_mpi_dprint (MHD_gnutls_datum_t * dest, const mpi_t a)
00145 {
00146   int ret;
00147   opaque *buf = NULL;
00148   size_t bytes = 0;
00149 
00150   if (dest == NULL || a == NULL)
00151     return GNUTLS_E_INVALID_REQUEST;
00152 
00153   gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &bytes, a);
00154 
00155   if (bytes != 0)
00156     buf = MHD_gnutls_malloc (bytes);
00157   if (buf == NULL)
00158     return GNUTLS_E_MEMORY_ERROR;
00159 
00160   ret = gcry_mpi_print (GCRYMPI_FMT_USG, buf, bytes, &bytes, a);
00161   if (!ret)
00162     {
00163       dest->data = buf;
00164       dest->size = bytes;
00165       return 0;
00166     }
00167 
00168   MHD_gnutls_free (buf);
00169   return GNUTLS_E_MPI_PRINT_FAILED;
00170 }
00171 
00172 
00173 /* this function reads an integer
00174  * from asn1 structs. Combines the read and mpi_scan
00175  * steps.
00176  */
00177 int
00178 MHD__gnutls_x509_read_int (ASN1_TYPE node, const char *value, mpi_t * ret_mpi)
00179 {
00180   int result;
00181   size_t s_len;
00182   opaque *tmpstr = NULL;
00183   int tmpstr_size;
00184 
00185   tmpstr_size = 0;
00186   result = MHD__asn1_read_value (node, value, NULL, &tmpstr_size);
00187   if (result != ASN1_MEM_ERROR)
00188     {
00189       MHD_gnutls_assert ();
00190       return MHD_gtls_asn2err (result);
00191     }
00192 
00193   tmpstr = MHD_gnutls_alloca (tmpstr_size);
00194   if (tmpstr == NULL)
00195     {
00196       MHD_gnutls_assert ();
00197       return GNUTLS_E_MEMORY_ERROR;
00198     }
00199 
00200   result = MHD__asn1_read_value (node, value, tmpstr, &tmpstr_size);
00201   if (result != ASN1_SUCCESS)
00202     {
00203       MHD_gnutls_assert ();
00204       MHD_gnutls_afree (tmpstr);
00205       return MHD_gtls_asn2err (result);
00206     }
00207 
00208   s_len = tmpstr_size;
00209   if (MHD_gtls_mpi_scan (ret_mpi, tmpstr, &s_len) != 0)
00210     {
00211       MHD_gnutls_assert ();
00212       MHD_gnutls_afree (tmpstr);
00213       return GNUTLS_E_MPI_SCAN_FAILED;
00214     }
00215 
00216   MHD_gnutls_afree (tmpstr);
00217 
00218   return 0;
00219 }
00220 
00221 /* Writes the specified integer into the specified node.
00222  */
00223 int
00224 MHD__gnutls_x509_write_int (ASN1_TYPE node, const char *value, mpi_t mpi,
00225                             int lz)
00226 {
00227   opaque *tmpstr;
00228   size_t s_len;
00229   int result;
00230 
00231   s_len = 0;
00232   if (lz)
00233     result = MHD_gtls_mpi_print_lz (NULL, &s_len, mpi);
00234   else
00235     result = MHD_gtls_mpi_print (NULL, &s_len, mpi);
00236 
00237   tmpstr = MHD_gnutls_alloca (s_len);
00238   if (tmpstr == NULL)
00239     {
00240       MHD_gnutls_assert ();
00241       return GNUTLS_E_MEMORY_ERROR;
00242     }
00243 
00244   if (lz)
00245     result = MHD_gtls_mpi_print_lz (tmpstr, &s_len, mpi);
00246   else
00247     result = MHD_gtls_mpi_print (tmpstr, &s_len, mpi);
00248 
00249   if (result != 0)
00250     {
00251       MHD_gnutls_assert ();
00252       MHD_gnutls_afree (tmpstr);
00253       return GNUTLS_E_MPI_PRINT_FAILED;
00254     }
00255 
00256   result = MHD__asn1_write_value (node, value, tmpstr, s_len);
00257 
00258   MHD_gnutls_afree (tmpstr);
00259 
00260   if (result != ASN1_SUCCESS)
00261     {
00262       MHD_gnutls_assert ();
00263       return MHD_gtls_asn2err (result);
00264     }
00265 
00266   return 0;
00267 }

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