mpi.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 #include <gnutls_int.h>
00026 #include <gnutls_errors.h>
00027 #include <gnutls_global.h>
00028 #include <libtasn1.h>
00029 #include <gnutls_datum.h>
00030 #include "common.h"
00031 #include "x509.h"
00032 #include <gnutls_num.h>
00033 #include "mpi.h"
00034 
00035 /*
00036  * some x509 certificate parsing functions that relate to MPI parameter
00037  * extraction. This reads the BIT STRING subjectPublicKey.
00038  * Returns 2 parameters (m,e).
00039  */
00040 int
00041 MHD__gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params)
00042 {
00043   int result;
00044   ASN1_TYPE spk = ASN1_TYPE_EMPTY;
00045 
00046   if ((result =
00047        MHD__asn1_create_element (MHD__gnutls_getMHD__gnutls_asn (),
00048                                  "GNUTLS.RSAPublicKey",
00049                                  &spk)) != ASN1_SUCCESS)
00050     {
00051       MHD_gnutls_assert ();
00052       return MHD_gtls_asn2err (result);
00053     }
00054 
00055   result = MHD__asn1_der_decoding (&spk, der, dersize, NULL);
00056 
00057   if (result != ASN1_SUCCESS)
00058     {
00059       MHD_gnutls_assert ();
00060       MHD__asn1_delete_structure (&spk);
00061       return MHD_gtls_asn2err (result);
00062     }
00063 
00064   if ((result = MHD__gnutls_x509_read_int (spk, "modulus", &params[0])) < 0)
00065     {
00066       MHD_gnutls_assert ();
00067       MHD__asn1_delete_structure (&spk);
00068       return GNUTLS_E_ASN1_GENERIC_ERROR;
00069     }
00070 
00071   if ((result =
00072        MHD__gnutls_x509_read_int (spk, "publicExponent", &params[1])) < 0)
00073     {
00074       MHD_gnutls_assert ();
00075       MHD_gtls_mpi_release (&params[0]);
00076       MHD__asn1_delete_structure (&spk);
00077       return GNUTLS_E_ASN1_GENERIC_ERROR;
00078     }
00079 
00080   MHD__asn1_delete_structure (&spk);
00081 
00082   return 0;
00083 
00084 }
00085 
00086 
00087 /* Extracts DSA and RSA parameters from a certificate.
00088  */
00089 int
00090 MHD__gnutls_x509_crt_get_mpis (MHD_gnutls_x509_crt_t cert,
00091                                mpi_t * params, int *params_size)
00092 {
00093   int result;
00094   int pk_algorithm;
00095   MHD_gnutls_datum_t tmp = { NULL, 0 };
00096 
00097   /* Read the algorithm's OID
00098    */
00099   pk_algorithm = MHD_gnutls_x509_crt_get_pk_algorithm (cert, NULL);
00100 
00101   /* Read the algorithm's parameters
00102    */
00103   result
00104     = MHD__gnutls_x509_read_value (cert->cert,
00105                                    "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
00106                                    &tmp, 2);
00107 
00108   if (result < 0)
00109     {
00110       MHD_gnutls_assert ();
00111       return result;
00112     }
00113 
00114   switch (pk_algorithm)
00115     {
00116     case MHD_GNUTLS_PK_RSA:
00117       /* params[0] is the modulus,
00118        * params[1] is the exponent
00119        */
00120       if (*params_size < RSA_PUBLIC_PARAMS)
00121         {
00122           MHD_gnutls_assert ();
00123           /* internal error. Increase the mpi_ts in params */
00124           result = GNUTLS_E_INTERNAL_ERROR;
00125           goto error;
00126         }
00127 
00128       if ((result =
00129            MHD__gnutls_x509_read_rsa_params (tmp.data, tmp.size, params)) < 0)
00130         {
00131           MHD_gnutls_assert ();
00132           goto error;
00133         }
00134       *params_size = RSA_PUBLIC_PARAMS;
00135 
00136       break;
00137     default:
00138       /* other types like DH
00139        * currently not supported
00140        */
00141       MHD_gnutls_assert ();
00142       result = GNUTLS_E_X509_CERTIFICATE_ERROR;
00143       goto error;
00144     }
00145 
00146   result = 0;
00147 
00148 error:MHD__gnutls_free_datum (&tmp);
00149   return result;
00150 }
00151 
00152 /*
00153  * some x509 certificate functions that relate to MPI parameter
00154  * setting. This writes the BIT STRING subjectPublicKey.
00155  * Needs 2 parameters (m,e).
00156  *
00157  * Allocates the space used to store the DER data.
00158  */
00159 int
00160 MHD__gnutls_x509_write_rsa_params (mpi_t * params,
00161                                    int params_size, MHD_gnutls_datum_t * der)
00162 {
00163   int result;
00164   ASN1_TYPE spk = ASN1_TYPE_EMPTY;
00165 
00166   der->data = NULL;
00167   der->size = 0;
00168 
00169   if (params_size < 2)
00170     {
00171       MHD_gnutls_assert ();
00172       result = GNUTLS_E_INVALID_REQUEST;
00173       goto cleanup;
00174     }
00175 
00176   if ((result =
00177        MHD__asn1_create_element (MHD__gnutls_getMHD__gnutls_asn (),
00178                                  "GNUTLS.RSAPublicKey",
00179                                  &spk)) != ASN1_SUCCESS)
00180     {
00181       MHD_gnutls_assert ();
00182       return MHD_gtls_asn2err (result);
00183     }
00184 
00185   result = MHD__gnutls_x509_write_int (spk, "modulus", params[0], 0);
00186   if (result < 0)
00187     {
00188       MHD_gnutls_assert ();
00189       goto cleanup;
00190     }
00191 
00192   result = MHD__gnutls_x509_write_int (spk, "publicExponent", params[1], 0);
00193   if (result < 0)
00194     {
00195       MHD_gnutls_assert ();
00196       goto cleanup;
00197     }
00198 
00199   result = MHD__gnutls_x509_der_encode (spk, "", der, 0);
00200   if (result < 0)
00201     {
00202       MHD_gnutls_assert ();
00203       goto cleanup;
00204     }
00205 
00206   MHD__asn1_delete_structure (&spk);
00207   return 0;
00208 
00209 cleanup:MHD__asn1_delete_structure (&spk);
00210 
00211   return result;
00212 }
Generated by  doxygen 1.6.2-20100208