]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
gnutls_pk_params_st is used internally to transfer public key parameters. This replac...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 22 May 2011 09:55:33 +0000 (11:55 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 22 May 2011 11:37:59 +0000 (13:37 +0200)
46 files changed:
lib/abstract_int.h
lib/algorithms.h
lib/algorithms/ecc.c
lib/auth/anon.h
lib/auth/ecdh_common.c
lib/auth/ecdh_common.h
lib/auth/rsa.c
lib/auth/rsa_export.c
lib/ext/ecc.c
lib/gnutls.asn
lib/gnutls_asn1_tab.c
lib/gnutls_ecc.c
lib/gnutls_ecc.h
lib/gnutls_errors.c
lib/gnutls_int.h
lib/gnutls_pk.c
lib/gnutls_pk.h
lib/gnutls_privkey.c
lib/gnutls_pubkey.c
lib/gnutls_rsa_export.c
lib/gnutls_rsa_export.h
lib/gnutls_sig.c
lib/gnutls_sig.h
lib/gnutls_state.c
lib/gnutls_state.h
lib/includes/gnutls/crypto.h
lib/includes/gnutls/gnutls.h.in
lib/libgnutls.map
lib/nettle/ecc_test.c
lib/nettle/pk.c
lib/openpgp/openpgp_int.h
lib/openpgp/pgp.c
lib/openpgp/privkey.c
lib/x509/Makefile.am
lib/x509/common.c
lib/x509/common.h
lib/x509/crq.c
lib/x509/key_decode.c [new file with mode: 0644]
lib/x509/key_encode.c [new file with mode: 0644]
lib/x509/mpi.c
lib/x509/privkey.c
lib/x509/privkey_pkcs8.c
lib/x509/verify.c
lib/x509/x509.c
lib/x509/x509_int.h
lib/x509/x509_write.c

index 45440fef38279f190e7e0b16cfcda9c16dab7e98..106067979743e4e380d55857d6f709edc8537dae 100644 (file)
@@ -4,13 +4,14 @@
 #include <gnutls/abstract.h>
 
 int _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
-                                     bigint_t * params, int *params_size);
+                                     gnutls_pk_params_st*);
 
+int pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st* params);
 int _gnutls_pubkey_compatible_with_sig(gnutls_pubkey_t pubkey, gnutls_protocol_t ver, 
   gnutls_sign_algorithm_t sign);
 int _gnutls_pubkey_is_over_rsa_512(gnutls_pubkey_t pubkey);
 int
 _gnutls_pubkey_get_mpis (gnutls_pubkey_t key,
-                                 bigint_t * params, int *params_size);
+                                 gnutls_pk_params_st * params);
 
 #endif
index 5d7d7fa24885736adc942025a9da3faa318e9253..205a2c19ab0976519b775c92a6ab4b25067111d5 100644 (file)
@@ -129,7 +129,8 @@ unsigned int _gnutls_pk_bits_to_subgroup_bits (unsigned int pk_bits);
 struct gnutls_ecc_curve_entry_st
 {
   const char *name;
-  ecc_curve_t id;
+  const char* oid;
+  gnutls_ecc_curve_t id;
   int tls_id; /* The RFC4492 namedCurve ID */
   int size; /* the size in bytes */
 
@@ -148,11 +149,13 @@ struct gnutls_ecc_curve_entry_st
 };
 typedef struct gnutls_ecc_curve_entry_st gnutls_ecc_curve_entry_st;
 
-const char * _gnutls_ecc_curve_get_name (ecc_curve_t curve);
-const gnutls_ecc_curve_entry_st * _gnutls_ecc_curve_get_params (ecc_curve_t curve);
-int _gnutls_ecc_curve_get_size (ecc_curve_t curve);
-ecc_curve_t _gnutls_ecc_curve_get_id (const char *name);
+const gnutls_ecc_curve_entry_st * _gnutls_ecc_curve_get_params (gnutls_ecc_curve_t curve);
+gnutls_ecc_curve_t _gnutls_ecc_curve_get_id (const char *name);
 int _gnutls_tls_id_to_ecc_curve (int num);
-int _gnutls_ecc_curve_get_tls_id (ecc_curve_t supported_ecc);
+int _gnutls_ecc_curve_get_tls_id (gnutls_ecc_curve_t supported_ecc);
+const char * _gnutls_ecc_curve_get_oid (gnutls_ecc_curve_t curve);
+gnutls_ecc_curve_t _gnutls_oid_to_ecc_curve (const char* oid);
+
+#define MAX_ECC_CURVE_SIZE 66
 
 #endif
index 4bd2a130ba2b5ffdcdb047ba7bbe914181b1ddec..2ba286982ee65c715f18e0c2a8274495e33b6e52 100644 (file)
@@ -34,6 +34,7 @@
 static const gnutls_ecc_curve_entry_st ecc_curves[] = {
   {
     .name = "SECP224R1", 
+    .oid = "1.3.132.0.33",
     .id = GNUTLS_ECC_CURVE_SECP224R1,
     .tls_id = 21,
     .size = 28,
@@ -46,6 +47,7 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = {
   },
   {
     .name = "SECP256R1", 
+    .oid = "1.2.840.10045.3.1.7",
     .id = GNUTLS_ECC_CURVE_SECP256R1,
     .tls_id = 23,
     .size = 32,
@@ -58,6 +60,7 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = {
   },
   {
     .name = "SECP384R1",
+    .oid = "1.3.132.0.34",
     .id = GNUTLS_ECC_CURVE_SECP384R1,
     .tls_id = 24,
     .size = 48,
@@ -70,6 +73,7 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = {
   },
   {
     .name = "SECP521R1",
+    .oid = "1.3.132.0.35",
     .id = GNUTLS_ECC_CURVE_SECP521R1,
     .tls_id = 25,
     .size = 66,
@@ -93,7 +97,7 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = {
 int
 _gnutls_tls_id_to_ecc_curve (int num)
 {
-  ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID;
+  gnutls_ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID;
 
   GNUTLS_ECC_CURVE_LOOP (
   if (p->tls_id == num) 
@@ -110,7 +114,7 @@ _gnutls_tls_id_to_ecc_curve (int num)
  * Returns a negative number on error.
  */
 int
-_gnutls_ecc_curve_get_tls_id (ecc_curve_t supported_ecc)
+_gnutls_ecc_curve_get_tls_id (gnutls_ecc_curve_t supported_ecc)
 {
   int ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
 
@@ -125,6 +129,27 @@ _gnutls_ecc_curve_get_tls_id (ecc_curve_t supported_ecc)
   return ret;
 }
 
+/*-
+ * _gnutls_oid_to_ecc_curve:
+ * @oid: is a curve's OID
+ *
+ * Returns: return a #gnutls_ecc_curve_t value corresponding to
+ *   the specified OID, or %GNUTLS_ECC_CURVE_INVALID on error.
+ -*/
+gnutls_ecc_curve_t _gnutls_oid_to_ecc_curve (const char* oid)
+{
+  gnutls_ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID;
+
+  GNUTLS_ECC_CURVE_LOOP (
+  if (strcasecmp (p->oid, oid) == 0) 
+    {
+      ret = p->id;
+      break;
+    }
+  );
+
+  return ret;
+}
 
 /*-
  * _gnutls_ecc_curve_get_id:
@@ -132,13 +157,13 @@ _gnutls_ecc_curve_get_tls_id (ecc_curve_t supported_ecc)
  *
  * The names are compared in a case insensitive way.
  *
- * Returns: return a #ecc_curve_t value corresponding to
- *   the specified cipher, or %GNUTLS_ECC_CURVE_INVALID on error.
+ * Returns: return a #gnutls_ecc_curve_t value corresponding to
+ *   the specified curve, or %GNUTLS_ECC_CURVE_INVALID on error.
  -*/
-ecc_curve_t
+gnutls_ecc_curve_t
 _gnutls_ecc_curve_get_id (const char *name)
 {
-  ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID;
+  gnutls_ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID;
 
   GNUTLS_ECC_CURVE_LOOP (
   if (strcasecmp (p->name, name) == 0) 
@@ -151,24 +176,49 @@ _gnutls_ecc_curve_get_id (const char *name)
   return ret;
 }
 
+/**
+ * gnutls_ecc_curve_get_name:
+ * @curve: is an ECC curve
+ *
+ * Convert a #gnutls_ecc_curve_t value to a string.
+ *
+ * Returns: a string that contains the name of the specified
+ *   curve or %NULL.
+ **/
+const char *
+gnutls_ecc_curve_get_name (gnutls_ecc_curve_t curve)
+{
+  const char *ret = NULL;
+
+  GNUTLS_ECC_CURVE_LOOP(
+    if (p->id == curve)
+      {
+        ret = p->name;
+        break;
+      }
+  );
+
+  return ret;
+}
+
 /*-
- * _gnutls_ecc_curve_get_name:
+ * _gnutls_ecc_curve_get_oid:
  * @curve: is an ECC curve
  *
- * Convert a #ecc_curve_t value to a string.
+ * Convert a #gnutls_ecc_curve_t value to a string.
  *
  * Returns: a string that contains the name of the specified
  *   curve or %NULL.
  -*/
 const char *
-_gnutls_ecc_curve_get_name (ecc_curve_t curve)
+_gnutls_ecc_curve_get_oid (gnutls_ecc_curve_t curve)
 {
   const char *ret = NULL;
 
   GNUTLS_ECC_CURVE_LOOP(
     if (p->id == curve)
       {
-        ret = p->name;
+        ret = p->oid;
         break;
       }
   );
@@ -185,7 +235,7 @@ _gnutls_ecc_curve_get_name (ecc_curve_t curve)
  * Returns: a pointer to #gnutls_ecc_curve_entry_st or %NULL.
  -*/
 const gnutls_ecc_curve_entry_st *
-_gnutls_ecc_curve_get_params (ecc_curve_t curve)
+_gnutls_ecc_curve_get_params (gnutls_ecc_curve_t curve)
 {
   const gnutls_ecc_curve_entry_st *ret = NULL;
 
@@ -200,15 +250,15 @@ _gnutls_ecc_curve_get_params (ecc_curve_t curve)
   return ret;
 }
 
-/*-
- * _gnutls_ecc_curve_get_size:
+/**
+ * gnutls_ecc_curve_get_size:
  * @curve: is an ECC curve
  *
  * Returns the size in bytes of the curve.
  *
  * Returns: a the size or zero.
-*/
-int _gnutls_ecc_curve_get_size (ecc_curve_t curve)
**/
+int gnutls_ecc_curve_get_size (gnutls_ecc_curve_t curve)
 {
   int ret = 0;
 
index b2616df2474943169e63277210baa235fb34b00c..ce51f53376b34c600252178f529f18c967dab18b 100644 (file)
@@ -44,7 +44,7 @@ typedef struct gnutls_anon_client_credentials_st
 typedef struct anon_auth_info_st
 {
   dh_info_st dh;
-  ecc_curve_t curve;
+  gnutls_ecc_curve_t curve;
 } *anon_auth_info_t;
 
 typedef struct anon_auth_info_st anon_auth_info_st;
index 556f34a253ab257bf21bc4a85d688b14fadded77..f04526a5ec4031dad5ce8f57da3f25c91ce88a2f 100644 (file)
@@ -75,7 +75,7 @@ int ret;
 int
 _gnutls_proc_ecdh_common_client_kx (gnutls_session_t session,
                                   opaque * data, size_t _data_size,
-                                  ecc_curve_t curve)
+                                  gnutls_ecc_curve_t curve)
 {
   ssize_t data_size = _data_size;
   int ret, i = 0;
@@ -89,7 +89,7 @@ _gnutls_proc_ecdh_common_client_kx (gnutls_session_t session,
   i+=1;
 
   DECR_LEN (data_size, point_size);
-  ret = _gnutls_ecc_ansi_x963_import(curve, &data[i], point_size, &session->key->ecdh_x, &session->key->ecdh_y);
+  ret = _gnutls_ecc_ansi_x963_import(&data[i], point_size, &session->key->ecdh_x, &session->key->ecdh_y);
   if (ret < 0)
     return gnutls_assert_val(ret);
 
@@ -139,7 +139,7 @@ _gnutls_proc_ecdh_common_server_kx (gnutls_session_t session,
                                   opaque * data, size_t _data_size)
 {
   int i, ret, point_size;
-  ecc_curve_t curve;
+  gnutls_ecc_curve_t curve;
   ssize_t data_size = _data_size;
 
   i = 0;
@@ -162,7 +162,7 @@ _gnutls_proc_ecdh_common_server_kx (gnutls_session_t session,
   i++;
 
   DECR_LEN (data_size, point_size);
-  ret = _gnutls_ecc_ansi_x963_import(curve, &data[i], point_size, &session->key->ecdh_x, &session->key->ecdh_y);
+  ret = _gnutls_ecc_ansi_x963_import(&data[i], point_size, &session->key->ecdh_x, &session->key->ecdh_y);
   if (ret < 0)
     return gnutls_assert_val(ret);
 
@@ -174,7 +174,7 @@ _gnutls_proc_ecdh_common_server_kx (gnutls_session_t session,
 /* If the psk flag is set, then an empty psk_identity_hint will
  * be inserted */
 int _gnutls_ecdh_common_print_server_kx (gnutls_session_t session, gnutls_buffer_st* data,
-                                         ecc_curve_t curve)
+                                         gnutls_ecc_curve_t curve)
 {
   opaque p;
   int ret;
index 1fa6eba39a81c8ac5afcc80d06f699ed2553892d..9b7a92b653d0bd738cc66bc20c94203a9c8478e7 100644 (file)
@@ -30,9 +30,9 @@
 int _gnutls_gen_ecdh_common_client_kx (gnutls_session_t, gnutls_buffer_st*);
 int _gnutls_proc_ecdh_common_client_kx (gnutls_session_t session,
                                       opaque * data, size_t _data_size,
-                                      ecc_curve_t curve);
+                                      gnutls_ecc_curve_t curve);
 int _gnutls_ecdh_common_print_server_kx (gnutls_session_t, gnutls_buffer_st* data,
-                                         ecc_curve_t curve);
+                                         gnutls_ecc_curve_t curve);
 int _gnutls_proc_ecdh_common_server_kx (gnutls_session_t session, opaque * data,
                                       size_t _data_size);
 
index 4b162ffde2489074b118176c7674f1955cf0e75c..52aceaad154e1038e4ce74121f547a9f4365d144 100644 (file)
@@ -68,14 +68,11 @@ const mod_auth_st rsa_auth_struct = {
  */
 static int
 _gnutls_get_public_rsa_params (gnutls_session_t session,
-                               bigint_t params[MAX_PUBLIC_PARAMS_SIZE],
-                               int *params_len)
+                               gnutls_pk_params_st * params)
 {
   int ret;
   cert_auth_info_t info;
   gnutls_pcert_st peer_cert;
-  bigint_t tmp_params[RSA_PUBLIC_PARAMS];
-  int tmp_params_size;
   int i;
 
   /* normal non export case */
@@ -99,13 +96,8 @@ _gnutls_get_public_rsa_params (gnutls_session_t session,
       return ret;
     }
 
-  if (*params_len < RSA_PUBLIC_PARAMS)
-    {
-      gnutls_assert ();
-      ret = GNUTLS_E_INTERNAL_ERROR;
-      goto cleanup;
-    }
-  *params_len = RSA_PUBLIC_PARAMS;
+  gnutls_pk_params_init(params);
+  params->params_nr = RSA_PUBLIC_PARAMS;
 
   /* EXPORT case: */
   if (_gnutls_cipher_suite_get_kx_algo
@@ -120,29 +112,22 @@ _gnutls_get_public_rsa_params (gnutls_session_t session,
           goto cleanup;
         }
 
-      for (i = 0; i < *params_len; i++)
+      for (i = 0; i < params->params_nr; i++)
         {
-          params[i] = _gnutls_mpi_copy (session->key->rsa[i]);
+          params->params[i] = _gnutls_mpi_copy (session->key->rsa[i]);
         }
 
       ret = 0;
       goto cleanup;
     }
 
-  tmp_params_size = RSA_PUBLIC_PARAMS;
-  ret = _gnutls_pubkey_get_mpis(peer_cert.pubkey, tmp_params, &tmp_params_size);
+  ret = _gnutls_pubkey_get_mpis(peer_cert.pubkey, params);
   if (ret < 0)
     {
       ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
       goto cleanup;
     }
 
-  /* end of export case */
-  for (i = 0; i < *params_len; i++)
-    {
-      params[i] = _gnutls_mpi_copy (tmp_params[i]);
-    }
-    
   ret = 0;
   
 cleanup:
@@ -263,9 +248,8 @@ _gnutls_gen_rsa_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
   cert_auth_info_t auth = session->key->auth_info;
   gnutls_datum_t sdata;         /* data to send */
-  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
-  int params_len = MAX_PUBLIC_PARAMS_SIZE;
-  int ret, i;
+  gnutls_pk_params_st params;
+  int ret;
   gnutls_protocol_t ver;
 
   if (auth == NULL)
@@ -310,22 +294,21 @@ _gnutls_gen_rsa_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
   /* move RSA parameters to key (session).
    */
   if ((ret =
-       _gnutls_get_public_rsa_params (session, params, &params_len)) < 0)
+       _gnutls_get_public_rsa_params (session, &params)) < 0)
     {
       gnutls_assert ();
       return ret;
     }
 
-  if ((ret =
+  ret =
        _gnutls_pkcs1_rsa_encrypt (&sdata, &session->key->key,
-                                  params, params_len, 2)) < 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
+                                  &params, 2);
+
+  gnutls_pk_params_release(&params);
+
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
-  for (i = 0; i < params_len; i++)
-    _gnutls_mpi_release (&params[i]);
 
   if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
     {
index 91148637744f58ca099beb12f609614b9d613e78..baa990ff2727b7efdb9ea7b085f8c2bc81bb34b0 100644 (file)
@@ -72,7 +72,7 @@ const mod_auth_st rsa_export_auth_struct = {
  */
 static int
 _gnutls_get_private_rsa_params (gnutls_session_t session,
-                                bigint_t ** params, int *params_size)
+                                gnutls_pk_params_st** params)
 {
   int ret;
   gnutls_certificate_credentials_t cred;
@@ -116,8 +116,7 @@ _gnutls_get_private_rsa_params (gnutls_session_t session,
    * of 512 bits size. The params in the certificate are
    * used to sign this temporary stuff.
    */
-  *params_size = RSA_PRIVATE_PARAMS;
-  *params = rsa_params->params;
+  *params = &rsa_params->params;
 
   return 0;
 }
@@ -129,8 +128,7 @@ proc_rsa_export_client_kx (gnutls_session_t session, opaque * data,
   gnutls_datum_t plaintext;
   gnutls_datum_t ciphertext;
   int ret, dsize;
-  bigint_t *params;
-  int params_len;
+  gnutls_pk_params_st *params;
   int randomize_key = 0;
   ssize_t data_size = _data_size;
 
@@ -157,14 +155,14 @@ proc_rsa_export_client_kx (gnutls_session_t session, opaque * data,
       ciphertext.size = dsize;
     }
 
-  ret = _gnutls_get_private_rsa_params (session, &params, &params_len);
+  ret = _gnutls_get_private_rsa_params (session, &params);
   if (ret < 0)
     {
       gnutls_assert ();
       return ret;
     }
 
-  ret = _gnutls_pkcs1_rsa_decrypt (&plaintext, &ciphertext, params, params_len, 2);     /* btype==2 */
+  ret = _gnutls_pkcs1_rsa_decrypt (&plaintext, &ciphertext, params, 2);     /* btype==2 */
 
   if (ret < 0 || plaintext.size != GNUTLS_MASTER_SIZE)
     {
@@ -236,7 +234,7 @@ static int
 gen_rsa_export_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
   gnutls_rsa_params_t rsa_params;
-  const bigint_t *rsa_mpis;
+  const gnutls_pk_params_st *rsa_mpis;
   int ret = 0;
   gnutls_pcert_st *apr_cert_list;
   gnutls_privkey_t apr_pkey;
@@ -290,13 +288,13 @@ gen_rsa_export_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
       return ret;
     }
 
-  _gnutls_rsa_export_set_pubkey (session, rsa_mpis[1], rsa_mpis[0]);
+  _gnutls_rsa_export_set_pubkey (session, rsa_mpis->params[1], rsa_mpis->params[0]);
 
-  ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis[0], 0);
+  ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis->params[0], 0);
   if (ret < 0)
     return gnutls_assert_val(ret);
 
-  ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis[1], 0);
+  ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis->params[1], 0);
   if (ret < 0)
     return gnutls_assert_val(ret);
 
index b417a2bcfd1322b9d61318f15fb62200f0de35bf..7f744cacc1d01e10c75c6f6563e3350fae183024 100644 (file)
@@ -265,5 +265,5 @@ _gnutls_session_supports_ecc_curve (gnutls_session_t session, int ecc_type)
         }
     }
 
-  return GNUTLS_E_ECC_NO_SUPPORTED_CURVES;
+  return GNUTLS_E_ECC_UNSUPPORTED_CURVE;
 }
index f485c27d6d918dbada5d7d212230f4af55be1bbd..64e05199b34bf9560eef1835e88ab4fe43d76240 100644 (file)
@@ -89,5 +89,18 @@ DHParameter ::= SEQUENCE {
   privateValueLength  INTEGER OPTIONAL 
 }
 
+-- ECC from RFC5480
+ECPoint ::= OCTET STRING
+
+ECParameters ::= CHOICE {
+  namedCurve         OBJECT IDENTIFIER
+}
+
+ECPrivateKey ::= SEQUENCE {
+   Version       INTEGER, -- { ecPrivkeyVer1(1) }
+   privateKey    OCTET STRING,
+   parameters    [0] ECParameters OPTIONAL,
+   publicKey     [1] BIT STRING OPTIONAL
+}
 
 END
index ecac746e5d1982edae7b4e63820288134831a5ea..74af21df747231a6ce066e302ca20681482f812f 100644 (file)
@@ -55,9 +55,19 @@ const ASN1_ARRAY_TYPE gnutls_asn1_tab[] = {
   { "g", 1073741827, NULL },
   { "Y", 1073741827, NULL },
   { "priv", 3, NULL },
-  { "DHParameter", 536870917, NULL },
+  { "DHParameter", 1610612741, NULL },
   { "prime", 1073741827, NULL },
   { "base", 1073741827, NULL },
   { "privateValueLength", 16387, NULL },
+  { "ECPoint", 1073741831, NULL },
+  { "ECParameters", 1610612754, NULL },
+  { "namedCurve", 12, NULL },
+  { "ECPrivateKey", 536870917, NULL },
+  { "Version", 1073741827, NULL },
+  { "privateKey", 1073741831, NULL },
+  { "parameters", 1610637314, "ECParameters"},
+  { NULL, 2056, "0"},
+  { "publicKey", 536895494, NULL },
+  { NULL, 2056, "1"},
   { NULL, 0, NULL }
 };
index 6eb74eed67babb99e4d53b81fb1fc5c27b243575..60f1c8eae48500dbe0baca8500014b358cc8f9d7 100644 (file)
 #include <algorithms.h>
 #include <gnutls_errors.h>
 
-int _gnutls_ecc_ansi_x963_export(ecc_curve_t curve, bigint_t x, bigint_t y, gnutls_datum_t * out)
+int
+_gnutls_ecc_ansi_x963_export (gnutls_ecc_curve_t curve, bigint_t x, bigint_t y,
+                              gnutls_datum_t * out)
 {
-   int numlen = _gnutls_ecc_curve_get_size(curve);
-   int byte_size, ret;
-   size_t size;
-   
-   if (numlen == 0)
-     return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-   
-   out->size = 1 + 2*numlen;
-   
-   out->data = gnutls_malloc(out->size);
-   if (out->data == NULL)
-     return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
-
-   memset(out->data, 0, out->size);
-
-   /* store byte 0x04 */
-   out->data[0] = 0x04;
-
-   /* pad and store x */
-   byte_size = (_gnutls_mpi_get_nbits(x)+7)/8;
-   size = out->size - (1+(numlen-byte_size));
-   ret = _gnutls_mpi_print(x, &out->data[1+(numlen-byte_size)], &size);
-   if (ret < 0)
-     return gnutls_assert_val(ret);
-   
-   byte_size = (_gnutls_mpi_get_nbits(y)+7)/8;
-   size = out->size - (1+(numlen+numlen-byte_size));
-   ret = _gnutls_mpi_print(y, &out->data[1+numlen+numlen-byte_size], &size);
-   if (ret < 0)
-     return gnutls_assert_val(ret);
-
-   /* pad and store y */
-   return 0;
+  int numlen = gnutls_ecc_curve_get_size (curve);
+  int byte_size, ret;
+  size_t size;
+
+  if (numlen == 0)
+    return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST);
+
+  out->size = 1 + 2 * numlen;
+
+  out->data = gnutls_malloc (out->size);
+  if (out->data == NULL)
+    return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR);
+
+  memset (out->data, 0, out->size);
+
+  /* store byte 0x04 */
+  out->data[0] = 0x04;
+
+  /* pad and store x */
+  byte_size = (_gnutls_mpi_get_nbits (x) + 7) / 8;
+  size = out->size - (1 + (numlen - byte_size));
+  ret = _gnutls_mpi_print (x, &out->data[1 + (numlen - byte_size)], &size);
+  if (ret < 0)
+    return gnutls_assert_val (ret);
+
+  byte_size = (_gnutls_mpi_get_nbits (y) + 7) / 8;
+  size = out->size - (1 + (numlen + numlen - byte_size));
+  ret =
+    _gnutls_mpi_print (y, &out->data[1 + numlen + numlen - byte_size], &size);
+  if (ret < 0)
+    return gnutls_assert_val (ret);
+
+  /* pad and store y */
+  return 0;
 }
 
 
-int _gnutls_ecc_ansi_x963_import(ecc_curve_t curve, const opaque *in, unsigned long inlen, bigint_t* x, bigint_t* y)
+int
+_gnutls_ecc_ansi_x963_import (const opaque * in,
+                              unsigned long inlen, bigint_t * x, bigint_t * y)
+{
+  int ret;
+
+  /* must be odd */
+  if ((inlen & 1) == 0)
+    {
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  /* check for 4  */
+  if (in[0] != 4)
+    {
+      return gnutls_assert_val (GNUTLS_E_PARSING_ERROR);
+    }
+
+  /* read data */
+  ret = _gnutls_mpi_scan (x, in + 1, (inlen - 1) >> 1);
+  if (ret < 0)
+    return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR);
+
+  ret = _gnutls_mpi_scan (y, in + 1 + ((inlen - 1) >> 1), (inlen - 1) >> 1);
+  if (ret < 0)
+    {
+      _gnutls_mpi_release (x);
+      return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR);
+    }
+
+  return 0;
+}
+
+int _gnutls_ecc_curve_fill_params(gnutls_ecc_curve_t curve, gnutls_pk_params_st* params)
 {
-   int ret;
-   int numlen = _gnutls_ecc_curve_get_size(curve);
-   /* must be odd */
-   if ((inlen & 1) == 0 || numlen == 0) 
-     {
-       return GNUTLS_E_INVALID_REQUEST;
-     }
-
-   /* check for 4, 6 or 7 */
-   if (in[0] != 4 && in[0] != 6 && in[0] != 7) {
-      return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
-   }
-
-   /* read data */
-   ret = _gnutls_mpi_scan(x, in+1, (inlen-1)>>1);
-   if (ret < 0)
-     return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
-
-   ret = _gnutls_mpi_scan(y, in+1+((inlen-1)>>1), (inlen-1)>>1);
-   if (ret < 0)
-     {
-       _gnutls_mpi_release(x);
-       return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
-     }
-
-   return 0;
+const gnutls_ecc_curve_entry_st *st;
+uint8_t val[MAX_ECC_CURVE_SIZE];
+size_t val_size;
+int ret;
+
+  st = _gnutls_ecc_curve_get_params(curve);
+  if (st == NULL)
+    return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
+
+  val_size = sizeof(val);
+  ret = _gnutls_hex2bin(st->prime, strlen(st->prime), val, &val_size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+
+  ret = _gnutls_mpi_scan_nz(&params->params[0], val, val_size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+  params->params_nr++;
+  
+  val_size = sizeof(val);
+  ret = _gnutls_hex2bin(st->order, strlen(st->order), val, &val_size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+
+  ret = _gnutls_mpi_scan_nz(&params->params[1], val, val_size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+  params->params_nr++;
+  
+  val_size = sizeof(val);
+  ret = _gnutls_hex2bin(st->A, strlen(st->A), val, &val_size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+
+  ret = _gnutls_mpi_scan_nz(&params->params[2], val, val_size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+  params->params_nr++;
+  
+  val_size = sizeof(val);
+  ret = _gnutls_hex2bin(st->Gx, strlen(st->Gx), val, &val_size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+
+  ret = _gnutls_mpi_scan_nz(&params->params[3], val, val_size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+  params->params_nr++;
+  
+  val_size = sizeof(val);
+  ret = _gnutls_hex2bin(st->Gy, strlen(st->Gy), val, &val_size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+
+  ret = _gnutls_mpi_scan_nz(&params->params[4], val, val_size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+  params->params_nr++;
+  
+
+  return 0;
+
+cleanup:
+  gnutls_pk_params_release(params);
+  return ret;
+
 }
index 5f91ac58001743fdfee7f4e36d09bd3df7ebaf78..2ae454171b92860e85021aa013c37c0dd7275eb9 100644 (file)
@@ -1,2 +1,7 @@
-int _gnutls_ecc_ansi_x963_import(ecc_curve_t curve, const opaque *in, unsigned long inlen, bigint_t* x, bigint_t* y);
-int _gnutls_ecc_ansi_x963_export(ecc_curve_t curve, bigint_t x, bigint_t y, gnutls_datum_t * out);
+#ifndef GNUTLS_ECC_H
+# define GNUTLS_ECC_H
+
+int _gnutls_ecc_ansi_x963_import(const opaque *in, unsigned long inlen, bigint_t* x, bigint_t* y);
+int _gnutls_ecc_ansi_x963_export(gnutls_ecc_curve_t curve, bigint_t x, bigint_t y, gnutls_datum_t * out);
+int _gnutls_ecc_curve_fill_params(gnutls_ecc_curve_t curve, gnutls_pk_params_st* params);
+#endif
index 9f700b7e08c09a627725c0d627fa3e8368cbe50b..39bf11b3a9d918fe270325f232ea09c3719f8fda 100644 (file)
@@ -330,6 +330,8 @@ static const gnutls_error_entry error_algorithms[] = {
                GNUTLS_E_USER_ERROR, 1),
   ERROR_ENTRY (N_("No supported ECC curves were found"),
                GNUTLS_E_ECC_NO_SUPPORTED_CURVES, 1),
+  ERROR_ENTRY (N_("The curve is unsupported"),
+               GNUTLS_E_ECC_UNSUPPORTED_CURVE, 1),
   {NULL, NULL, 0, 0}
 };
 
index 8dbec242594f71a5af82d2856d3db2d587d45041..0f7609d6c25531d2cdd6a6534757e1025373322c 100644 (file)
@@ -225,15 +225,6 @@ typedef enum extensions_t
   GNUTLS_EXTENSION_SAFE_RENEGOTIATION = 65281   /* aka: 0xff01 */
 } extensions_t;
 
-typedef enum
-{
-  GNUTLS_ECC_CURVE_INVALID=0,
-  GNUTLS_ECC_CURVE_SECP224R1,
-  GNUTLS_ECC_CURVE_SECP256R1,
-  GNUTLS_ECC_CURVE_SECP384R1,
-  GNUTLS_ECC_CURVE_SECP521R1,
-} ecc_curve_t;
-
 typedef enum
 { CIPHER_STREAM, CIPHER_BLOCK } cipher_type_t;
 
@@ -486,7 +477,7 @@ typedef struct
   uint16_t max_record_recv_size;
   /* holds the negotiated certificate type */
   gnutls_certificate_type_t cert_type;
-  ecc_curve_t ecc_curve; /* holds the first supported ECC curve requested by client */
+  gnutls_ecc_curve_t ecc_curve; /* holds the first supported ECC curve requested by client */
   gnutls_protocol_t version;    /* moved here */
 
   /* FIXME: The following are not saved in the session storage
index 5fc3aa216f5b9654f3abb0878c8740dadf1cd4ae..358cef40ec318589967c69ed849f1905be434275 100644 (file)
@@ -45,7 +45,7 @@
 int
 _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
                            const gnutls_datum_t * plaintext,
-                           bigint_t * params, unsigned params_len,
+                           gnutls_pk_params_st * params, 
                            unsigned btype)
 {
   unsigned int i, pad;
@@ -53,14 +53,9 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
   opaque *edata, *ps;
   size_t k, psize;
   size_t mod_bits;
-  gnutls_pk_params_st pk_params;
   gnutls_datum_t to_encrypt, encrypted;
 
-  for (i = 0; i < params_len; i++)
-    pk_params.params[i] = params[i];
-  pk_params.params_nr = params_len;
-
-  mod_bits = _gnutls_mpi_get_nbits (params[0]);
+  mod_bits = _gnutls_mpi_get_nbits (params->params[0]);
   k = mod_bits / 8;
   if (mod_bits % 8 != 0)
     k++;
@@ -91,7 +86,7 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
     {
     case 2:
       /* using public key */
-      if (params_len < RSA_PUBLIC_PARAMS)
+      if (params->params_nr < RSA_PUBLIC_PARAMS)
         {
           gnutls_assert ();
           gnutls_free (edata);
@@ -120,7 +115,7 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
     case 1:
       /* using private key */
 
-      if (params_len < RSA_PRIVATE_PARAMS)
+      if (params->params_nr < RSA_PRIVATE_PARAMS)
         {
           gnutls_assert ();
           gnutls_free (edata);
@@ -144,10 +139,10 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
 
   if (btype == 2)               /* encrypt */
     ret =
-      _gnutls_pk_encrypt (GNUTLS_PK_RSA, &encrypted, &to_encrypt, &pk_params);
+      _gnutls_pk_encrypt (GNUTLS_PK_RSA, &encrypted, &to_encrypt, params);
   else                          /* sign */
     ret =
-      _gnutls_pk_sign (GNUTLS_PK_RSA, &encrypted, &to_encrypt, &pk_params);
+      _gnutls_pk_sign (GNUTLS_PK_RSA, &encrypted, &to_encrypt, params);
 
   gnutls_free (edata);
 
@@ -211,19 +206,14 @@ cleanup:
 int
 _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
                            const gnutls_datum_t * ciphertext,
-                           bigint_t * params, unsigned params_len,
+                           gnutls_pk_params_st* params,
                            unsigned btype)
 {
   unsigned int k, i;
   int ret;
   size_t esize, mod_bits;
-  gnutls_pk_params_st pk_params;
-
-  for (i = 0; i < params_len; i++)
-    pk_params.params[i] = params[i];
-  pk_params.params_nr = params_len;
 
-  mod_bits = _gnutls_mpi_get_nbits (params[0]);
+  mod_bits = _gnutls_mpi_get_nbits (params->params[0]);
   k = mod_bits / 8;
   if (mod_bits % 8 != 0)
     k++;
@@ -242,12 +232,12 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
   if (btype == 2)
     {
       ret =
-        _gnutls_pk_decrypt (GNUTLS_PK_RSA, plaintext, ciphertext, &pk_params);
+        _gnutls_pk_decrypt (GNUTLS_PK_RSA, plaintext, ciphertext, params);
     }
   else
     {
       ret =
-        _gnutls_pk_encrypt (GNUTLS_PK_RSA, plaintext, ciphertext, &pk_params);
+        _gnutls_pk_encrypt (GNUTLS_PK_RSA, plaintext, ciphertext, params);
     }
 
   if (ret < 0)
@@ -324,8 +314,9 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
 
 int
 _gnutls_rsa_verify (const gnutls_datum_t * vdata,
-                    const gnutls_datum_t * ciphertext, bigint_t * params,
-                    int params_len, int btype)
+                    const gnutls_datum_t * ciphertext, 
+                    gnutls_pk_params_st * params,
+                    int btype)
 {
 
   gnutls_datum_t plain;
@@ -333,7 +324,7 @@ _gnutls_rsa_verify (const gnutls_datum_t * vdata,
 
   /* decrypt signature */
   if ((ret =
-       _gnutls_pkcs1_rsa_decrypt (&plain, ciphertext, params, params_len,
+       _gnutls_pkcs1_rsa_decrypt (&plain, ciphertext, params,
                                   btype)) < 0)
     {
       gnutls_assert ();
@@ -410,17 +401,11 @@ _gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s)
  */
 int
 _gnutls_dsa_sign (gnutls_datum_t * signature,
-                  const gnutls_datum_t * hash, bigint_t * params,
-                  unsigned int params_len)
+                  const gnutls_datum_t * hash, 
+                  gnutls_pk_params_st * params)
 {
   int ret;
-  size_t i;
   size_t k;
-  gnutls_pk_params_st pk_params;
-
-  for (i = 0; i < params_len; i++)
-    pk_params.params[i] = params[i];
-  pk_params.params_nr = params_len;
 
   k = hash->size;
   if (k < 20)
@@ -429,7 +414,7 @@ _gnutls_dsa_sign (gnutls_datum_t * signature,
       return GNUTLS_E_PK_SIGN_FAILED;
     }
 
-  ret = _gnutls_pk_sign (GNUTLS_PK_DSA, signature, hash, &pk_params);
+  ret = _gnutls_pk_sign (GNUTLS_PK_DSA, signature, hash, params);
   /* rs[0], rs[1] now hold r,s */
 
   if (ret < 0)
@@ -493,16 +478,11 @@ _gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r,
  */
 int
 _gnutls_dsa_verify (const gnutls_datum_t * vdata,
-                    const gnutls_datum_t * sig_value, bigint_t * params,
-                    int params_len)
+                    const gnutls_datum_t * sig_value,
+                    gnutls_pk_params_st* params)
 {
 
-  int ret, i;
-  gnutls_pk_params_st pk_params;
-
-  for (i = 0; i < params_len; i++)
-    pk_params.params[i] = params[i];
-  pk_params.params_nr = params_len;
+  int ret;
 
   if (vdata->size < 20)
     { /* SHA1 or better only */
@@ -511,7 +491,7 @@ _gnutls_dsa_verify (const gnutls_datum_t * vdata,
     }
 
   /* decrypt signature */
-  ret = _gnutls_pk_verify (GNUTLS_PK_DSA, vdata, sig_value, &pk_params);
+  ret = _gnutls_pk_verify (GNUTLS_PK_DSA, vdata, sig_value, params);
 
   if (ret < 0)
     {
@@ -523,68 +503,21 @@ _gnutls_dsa_verify (const gnutls_datum_t * vdata,
 }
 
 /* some generic pk functions */
-static int
-_generate_params (int algo, bigint_t * resarr, unsigned int *resarr_len,
-                  int bits)
-{
-  gnutls_pk_params_st params;
-  int ret;
-  unsigned int i;
-
-  ret = _gnutls_pk_generate (algo, bits, &params);
-
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
-
-  if (resarr && resarr_len && *resarr_len >= params.params_nr)
-    {
-      *resarr_len = params.params_nr;
-      for (i = 0; i < params.params_nr; i++)
-        resarr[i] = params.params[i];
-    }
-  else
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-  return 0;
-}
-
-
 
-int
-_gnutls_rsa_generate_params (bigint_t * resarr, unsigned int *resarr_len,
-                             int bits)
-{
-  return _generate_params (GNUTLS_PK_RSA, resarr, resarr_len, bits);
-}
-
-int
-_gnutls_dsa_generate_params (bigint_t * resarr, unsigned int *resarr_len,
-                             int bits)
-{
-  return _generate_params (GNUTLS_PK_DSA, resarr, resarr_len, bits);
-}
-
-int
-_gnutls_pk_params_copy (gnutls_pk_params_st * dst, bigint_t * params,
-                        int params_len)
+int _gnutls_pk_params_copy (gnutls_pk_params_st * dst, const gnutls_pk_params_st * src)
 {
   int i, j;
   dst->params_nr = 0;
 
-  if (params_len == 0 || params == NULL)
+  if (src == NULL || src->params_nr == 0)
     {
       gnutls_assert ();
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  for (i = 0; i < params_len; i++)
+  for (i = 0; i < src->params_nr; i++)
     {
-      dst->params[i] = _gnutls_mpi_set (NULL, params[i]);
+      dst->params[i] = _gnutls_mpi_set (NULL, src->params[i]);
       if (dst->params[i] == NULL)
         {
           for (j = 0; j < i; j++)
@@ -611,14 +544,15 @@ gnutls_pk_params_release (gnutls_pk_params_st * p)
     {
       _gnutls_mpi_release (&p->params[i]);
     }
+  p->params_nr = 0;
 }
 
 int
-_gnutls_calc_rsa_exp (bigint_t * params, unsigned int params_size)
+_gnutls_calc_rsa_exp (gnutls_pk_params_st* params)
 {
-  bigint_t tmp = _gnutls_mpi_alloc_like (params[0]);
+  bigint_t tmp = _gnutls_mpi_alloc_like (params->params[0]);
 
-  if (params_size < RSA_PRIVATE_PARAMS - 2)
+  if (params->params_nr < RSA_PRIVATE_PARAMS - 2)
     {
       gnutls_assert ();
       return GNUTLS_E_INTERNAL_ERROR;
@@ -631,15 +565,15 @@ _gnutls_calc_rsa_exp (bigint_t * params, unsigned int params_size)
     }
 
   /* [6] = d % p-1, [7] = d % q-1 */
-  _gnutls_mpi_sub_ui (tmp, params[3], 1);
-  params[6] = _gnutls_mpi_mod (params[2] /*d */ , tmp);
+  _gnutls_mpi_sub_ui (tmp, params->params[3], 1);
+  params->params[6] = _gnutls_mpi_mod (params->params[2] /*d */ , tmp);
 
-  _gnutls_mpi_sub_ui (tmp, params[4], 1);
-  params[7] = _gnutls_mpi_mod (params[2] /*d */ , tmp);
+  _gnutls_mpi_sub_ui (tmp, params->params[4], 1);
+  params->params[7] = _gnutls_mpi_mod (params->params[2] /*d */ , tmp);
 
   _gnutls_mpi_release (&tmp);
 
-  if (params[7] == NULL || params[6] == NULL)
+  if (params->params[7] == NULL || params->params[6] == NULL)
     {
       gnutls_assert ();
       return GNUTLS_E_MEMORY_ERROR;
@@ -649,8 +583,8 @@ _gnutls_calc_rsa_exp (bigint_t * params, unsigned int params_size)
 }
 
 int
-_gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk, bigint_t * params,
-                               int params_size,
+_gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk, 
+                               gnutls_pk_params_st* params,
                                gnutls_digest_algorithm_t * dig,
                                unsigned int *mand)
 {
@@ -663,6 +597,6 @@ _gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk, bigint_t * params,
     }
 
   return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) dig,
-                                        NULL, pk, params, params_size);
+                                        NULL, pk, params);
 
 }
index 07a1acd7e97a272dbe833b38c47fb6c7d5eb5371..1cdcf86227b7c76826ee90b66223a758afc36222 100644 (file)
@@ -45,32 +45,26 @@ _gnutls_pk_fixup (gnutls_pk_algorithm_t algo, gnutls_direction_t direction,
   return 0;
 }
 
-int _gnutls_pk_params_copy (gnutls_pk_params_st * dst, bigint_t * params,
-                            int params_len);
-
-int _gnutls_rsa_generate_params (bigint_t * resarr, unsigned int *resarr_len,
-                                 int bits);
-int _gnutls_dsa_generate_params (bigint_t * resarr, unsigned int *resarr_len,
-                                 int bits);
+int _gnutls_pk_params_copy (gnutls_pk_params_st * dst, const gnutls_pk_params_st * src);
 
 /* The internal PK interface */
 int _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
                                const gnutls_datum_t * plaintext,
-                               bigint_t * params, unsigned params_len,
+                               gnutls_pk_params_st * params,
                                unsigned btype);
 int _gnutls_dsa_sign (gnutls_datum_t * signature,
-                      const gnutls_datum_t * plaintext, bigint_t * params,
-                      unsigned params_len);
+                      const gnutls_datum_t * plaintext, gnutls_pk_params_st*);
 int _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
                                const gnutls_datum_t * ciphertext,
-                               bigint_t * params, unsigned params_len,
+                               gnutls_pk_params_st* params,
                                unsigned btype);
 int _gnutls_rsa_verify (const gnutls_datum_t * vdata,
-                        const gnutls_datum_t * ciphertext, bigint_t * params,
-                        int params_len, int btype);
+                        const gnutls_datum_t * ciphertext, 
+                        gnutls_pk_params_st*,
+                        int btype);
 int _gnutls_dsa_verify (const gnutls_datum_t * vdata,
-                        const gnutls_datum_t * sig_value, bigint_t * params,
-                        int params_len);
+                        const gnutls_datum_t * sig_value,
+                        gnutls_pk_params_st* params);
 
 int
 _gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s);
@@ -79,10 +73,10 @@ int
 _gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r,
                        bigint_t * s);
 
-int _gnutls_calc_rsa_exp (bigint_t * params, unsigned int params_size);
+int _gnutls_calc_rsa_exp (gnutls_pk_params_st*);
 
 int _gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk,
-                                   bigint_t * params, int params_size,
+                                   gnutls_pk_params_st*,
                                    gnutls_digest_algorithm_t * dig,
                                    unsigned int *mand);
 
index 2b92efb0f9cd0dafae1ecc98f13790ae8ce6c548..b71e04a2243cb5d270c0d574e18efce42d3d1fcb 100644 (file)
@@ -95,7 +95,7 @@ gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key, unsigned int *bits)
       return gnutls_pkcs11_privkey_get_pk_algorithm (key->key.pkcs11, bits);
     case GNUTLS_PRIVKEY_X509:
       if (bits)
-        *bits = _gnutls_mpi_get_nbits (key->key.x509->params[0]);
+        *bits = _gnutls_mpi_get_nbits (key->key.x509->params.params[0]);
       return gnutls_x509_privkey_get_pk_algorithm (key->key.x509);
     default:
       gnutls_assert ();
@@ -106,27 +106,20 @@ gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key, unsigned int *bits)
 
 static int
 privkey_to_pubkey (gnutls_pk_algorithm_t pk,
-                   const bigint_t * params, int params_size,
-                   bigint_t * new_params, int *new_params_size)
+                   const gnutls_pk_params_st* priv,
+                   gnutls_pk_params_st* pub)
 {
-  int ret, i;
+  int ret;
 
   switch (pk)
     {
     case GNUTLS_PK_RSA:
-      if (*new_params_size < RSA_PUBLIC_PARAMS
-          || params_size < RSA_PRIVATE_PARAMS)
-        {
-          gnutls_assert ();
-          return GNUTLS_E_INVALID_REQUEST;
-        }
-
-      new_params[0] = _gnutls_mpi_copy (params[0]);
-      new_params[1] = _gnutls_mpi_copy (params[1]);
+      pub->params[0] = _gnutls_mpi_copy (priv->params[0]);
+      pub->params[1] = _gnutls_mpi_copy (priv->params[1]);
 
-      *new_params_size = RSA_PUBLIC_PARAMS;
+      pub->params_nr = RSA_PUBLIC_PARAMS;
 
-      if (new_params[0] == NULL || new_params[1] == NULL)
+      if (pub->params[0] == NULL || pub->params[1] == NULL)
         {
           gnutls_assert ();
           ret = GNUTLS_E_MEMORY_ERROR;
@@ -135,22 +128,15 @@ privkey_to_pubkey (gnutls_pk_algorithm_t pk,
 
       break;
     case GNUTLS_PK_DSA:
-      if (*new_params_size < DSA_PUBLIC_PARAMS
-          || params_size < DSA_PRIVATE_PARAMS)
-        {
-          gnutls_assert ();
-          return GNUTLS_E_INVALID_REQUEST;
-        }
+      pub->params[0] = _gnutls_mpi_copy (priv->params[0]);
+      pub->params[1] = _gnutls_mpi_copy (priv->params[1]);
+      pub->params[2] = _gnutls_mpi_copy (priv->params[2]);
+      pub->params[3] = _gnutls_mpi_copy (priv->params[3]);
 
-      new_params[0] = _gnutls_mpi_copy (params[0]);
-      new_params[1] = _gnutls_mpi_copy (params[1]);
-      new_params[2] = _gnutls_mpi_copy (params[2]);
-      new_params[3] = _gnutls_mpi_copy (params[3]);
+      pub->params_nr = DSA_PUBLIC_PARAMS;
 
-      *new_params_size = DSA_PUBLIC_PARAMS;
-
-      if (new_params[0] == NULL || new_params[1] == NULL ||
-          new_params[2] == NULL || new_params[3] == NULL)
+      if (pub->params[0] == NULL || pub->params[1] == NULL ||
+          pub->params[2] == NULL || pub->params[3] == NULL)
         {
           gnutls_assert ();
           ret = GNUTLS_E_MEMORY_ERROR;
@@ -165,8 +151,7 @@ privkey_to_pubkey (gnutls_pk_algorithm_t pk,
 
   return 0;
 cleanup:
-  for (i = 0; i < *new_params_size; i++)
-    _gnutls_mpi_release (new_params[i]);
+  gnutls_pk_params_release(pub);
   return ret;
 }
 
@@ -175,7 +160,7 @@ cleanup:
  */
 int
 _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
-                                 bigint_t * params, int *params_size)
+                                 gnutls_pk_params_st * params)
 {
   int ret;
   gnutls_pk_algorithm_t pk = gnutls_privkey_get_pk_algorithm (key, NULL);
@@ -185,9 +170,8 @@ _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
 #ifdef ENABLE_OPENPGP
     case GNUTLS_PRIVKEY_OPENPGP:
       {
-        bigint_t tmp_params[MAX_PRIV_PARAMS_SIZE];
-        int tmp_params_size = MAX_PRIV_PARAMS_SIZE;
-        uint32_t kid[2], i;
+        gnutls_pk_params_st tmp_params;
+        uint32_t kid[2];
         uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
 
         ret =
@@ -197,13 +181,11 @@ _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
           {
             KEYID_IMPORT (kid, keyid);
             ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, kid,
-                                                    tmp_params,
-                                                    &tmp_params_size);
+                                                    &tmp_params);
           }
         else
           ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, NULL,
-                                                  tmp_params,
-                                                  &tmp_params_size);
+                                                  &tmp_params);
 
         if (ret < 0)
           {
@@ -212,21 +194,18 @@ _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
           }
 
         ret = privkey_to_pubkey (pk,
-                                 tmp_params, tmp_params_size,
-                                 params, params_size);
-
-        for (i = 0; i < tmp_params_size; i++)
-          _gnutls_mpi_release (&tmp_params[i]);
+                                 &tmp_params,
+                                 params);
 
+        gnutls_pk_params_release(&tmp_params);
       }
 
       break;
 #endif
     case GNUTLS_PRIVKEY_X509:
       ret = privkey_to_pubkey (pk,
-                               key->key.x509->params,
-                               key->key.x509->params_size, params,
-                               params_size);
+                               &key->key.x509->params,
+                               params);
       break;
     default:
       gnutls_assert ();
@@ -574,8 +553,8 @@ _gnutls_privkey_sign_hash (gnutls_privkey_t key,
                                                hash, signature);
     case GNUTLS_PRIVKEY_X509:
       return _gnutls_soft_sign (key->key.x509->pk_algorithm,
-                                key->key.x509->params,
-                                key->key.x509->params_size, hash, signature);
+                                &key->key.x509->params,
+                                hash, signature);
     default:
       gnutls_assert ();
       return GNUTLS_E_INVALID_REQUEST;
@@ -616,8 +595,8 @@ gnutls_privkey_decrypt_data (gnutls_privkey_t key,
 #endif
     case GNUTLS_PRIVKEY_X509:
       return _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext,
-                                        key->key.x509->params,
-                                        key->key.x509->params_size, 2);
+                                        &key->key.x509->params,
+                                        2);
     case GNUTLS_PRIVKEY_PKCS11:
       return _gnutls_pkcs11_privkey_decrypt_data (key->key.pkcs11,
                                                  flags,
index 0c60ea5287b0606042447056e32c16c326eed57c..c6ad39abc8a531ea3ed7fb93a01a9ed95ee3e90c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * GnuTLS PKCS#11 support
- * Copyright (C) 2010 Free Software Foundation
+ * Copyright (C) 2010,2011 Free Software Foundation
  * 
  * Author: Nikos Mavrogiannopoulos
  *
@@ -58,8 +58,7 @@ struct gnutls_pubkey_st
    *      [2] is g
    *      [3] is public key
    */
-  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
-  int params_size;              /* holds the size of MPI params */
+  gnutls_pk_params_st params;
 
   uint8_t openpgp_key_id[GNUTLS_OPENPGP_KEYID_SIZE];
   int openpgp_key_id_set;
@@ -67,15 +66,16 @@ struct gnutls_pubkey_st
   unsigned int key_usage;       /* bits from GNUTLS_KEY_* */
 };
 
-static int pubkey_to_bits(gnutls_pk_algorithm_t pk, bigint_t* params, int params_size)
+int pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st* params)
 {
   switch(pk) 
     {
       case GNUTLS_PK_RSA:
-        return _gnutls_mpi_get_nbits(params[0]);
+        return _gnutls_mpi_get_nbits(params->params[0]);
       case GNUTLS_PK_DSA:
-        if (params_size < 3) return 0;
-        return _gnutls_mpi_get_nbits(params[3]);
+        return _gnutls_mpi_get_nbits(params->params[3]);
+      case GNUTLS_PK_ECC:
+        return gnutls_ecc_curve_get_size(params->flags)*8;
       default:
         return 0;
     }
@@ -152,13 +152,7 @@ gnutls_pubkey_init (gnutls_pubkey_t * key)
 void
 gnutls_pubkey_deinit (gnutls_pubkey_t key)
 {
-int i;
-
-  for (i = 0; i < key->params_size; i++)
-    {
-      _gnutls_mpi_release (&key->params[i]);
-    }
-
+  gnutls_pk_params_release(&key->params);
   gnutls_free (key);
 }
 
@@ -186,29 +180,11 @@ gnutls_pubkey_import_x509 (gnutls_pubkey_t key, gnutls_x509_crt_t crt,
   if (ret < 0)
     key->key_usage = 0;
 
-  key->params_size = sizeof (key->params) / sizeof (key->params[0]);
-  switch (key->pk_algorithm)
+  ret = _gnutls_x509_crt_get_mpis (crt, &key->params);
+  if (ret < 0)
     {
-    case GNUTLS_PK_RSA:
-      ret = _gnutls_x509_crt_get_mpis (crt, key->params, &key->params_size);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          return ret;
-        }
-      break;
-    case GNUTLS_PK_DSA:
-      ret = _gnutls_x509_crt_get_mpis (crt, key->params, &key->params_size);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          return ret;
-        }
-
-      break;
-    default:
       gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
+      return ret;
     }
 
   return 0;
@@ -237,10 +213,7 @@ gnutls_pubkey_import_privkey (gnutls_pubkey_t key, gnutls_privkey_t pkey,
 
   key->key_usage = usage;
 
-  key->params_size = sizeof (key->params) / sizeof (key->params[0]);
-
-  return _gnutls_privkey_get_public_mpis (pkey, key->params,
-                                          &key->params_size);
+  return _gnutls_privkey_get_public_mpis (pkey, &key->params);
 }
 
 /**
@@ -272,7 +245,7 @@ gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key,
     }
 
   ret = _gnutls_pk_get_hash_algorithm (key->pk_algorithm,
-                                       key->params, key->params_size,
+                                       &key->params,
                                        hash, mand);
 
   return ret;
@@ -396,34 +369,10 @@ gnutls_pubkey_import_openpgp (gnutls_pubkey_t key,
       key->pk_algorithm = gnutls_openpgp_crt_get_subkey_pk_algorithm (crt, idx, NULL);
     }
 
-  switch (key->pk_algorithm)
-    {
-    case GNUTLS_PK_RSA:
-      key->params_size = MAX_PUBLIC_PARAMS_SIZE;
-      ret =
-        _gnutls_openpgp_crt_get_mpis (crt, k, key->params,
-                                      &key->params_size);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          return ret;
-        }
-      break;
-    case GNUTLS_PK_DSA:
-      key->params_size = MAX_PUBLIC_PARAMS_SIZE;
-      ret =
-        _gnutls_openpgp_crt_get_mpis (crt, k, key->params,
-                                      &key->params_size);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          return ret;
-        }
-      break;
-    default:
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
+  ret =
+    _gnutls_openpgp_crt_get_mpis (crt, k, &key->params);
+  if (ret < 0)
+     return gnutls_assert_val(ret);
 
   return 0;
 }
@@ -529,7 +478,7 @@ gnutls_pubkey_export (gnutls_pubkey_t key,
   result =
     _gnutls_x509_encode_and_copy_PKI_params (spk, "",
                                              key->pk_algorithm,
-                                             key->params, key->params_size);
+                                             &key->params);
   if (result < 0)
     {
       gnutls_assert ();
@@ -588,8 +537,8 @@ gnutls_pubkey_get_key_id (gnutls_pubkey_t key, unsigned int flags,
     }
 
   ret =
-    _gnutls_get_key_id (key->pk_algorithm, key->params,
-                        key->params_size, output_data, output_data_size);
+    _gnutls_get_key_id (key->pk_algorithm, &key->params,
+                        output_data, output_data_size);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -629,14 +578,14 @@ gnutls_pubkey_get_pk_rsa_raw (gnutls_pubkey_t key,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  ret = _gnutls_mpi_dprint (key->params[0], m);
+  ret = _gnutls_mpi_dprint (key->params.params[0], m);
   if (ret < 0)
     {
       gnutls_assert ();
       return ret;
     }
 
-  ret = _gnutls_mpi_dprint (key->params[1], e);
+  ret = _gnutls_mpi_dprint (key->params.params[1], e);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -681,7 +630,7 @@ gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key,
     }
 
   /* P */
-  ret = _gnutls_mpi_dprint (key->params[0], p);
+  ret = _gnutls_mpi_dprint (key->params.params[0], p);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -689,7 +638,7 @@ gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key,
     }
 
   /* Q */
-  ret = _gnutls_mpi_dprint (key->params[1], q);
+  ret = _gnutls_mpi_dprint (key->params.params[1], q);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -699,7 +648,7 @@ gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key,
 
 
   /* G */
-  ret = _gnutls_mpi_dprint (key->params[2], g);
+  ret = _gnutls_mpi_dprint (key->params.params[2], g);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -710,7 +659,7 @@ gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key,
 
 
   /* Y */
-  ret = _gnutls_mpi_dprint (key->params[3], y);
+  ret = _gnutls_mpi_dprint (key->params.params[3], y);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -795,8 +744,7 @@ gnutls_pubkey_import (gnutls_pubkey_t key,
       goto cleanup;
     }
 
-  key->params_size = sizeof (key->params) / sizeof (key->params[0]);
-  result = _gnutls_get_asn_mpis (spk, "", key->params, &key->params_size);
+  result = _gnutls_get_asn_mpis (spk, "", &key->params);
   if (result < 0)
     {
       gnutls_assert ();
@@ -807,7 +755,7 @@ gnutls_pubkey_import (gnutls_pubkey_t key,
    * fail.
    */
   key->pk_algorithm = _gnutls_x509_get_pk_algorithm (spk, "", NULL);
-  key->bits = pubkey_to_bits(key->pk_algorithm, key->params, key->params_size);
+  key->bits = pubkey_to_bits(key->pk_algorithm, &key->params);
 
   result = 0;
 
@@ -844,8 +792,7 @@ gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt, gnutls_pubkey_t key)
   result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert,
                                                     "tbsCertificate.subjectPublicKeyInfo",
                                                     key->pk_algorithm,
-                                                    key->params,
-                                                    key->params_size);
+                                                    &key->params);
 
   if (result < 0)
     {
@@ -884,7 +831,7 @@ gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq, gnutls_pubkey_t key)
   result = _gnutls_x509_encode_and_copy_PKI_params
     (crq->crq,
      "certificationRequestInfo.subjectPKInfo",
-     key->pk_algorithm, key->params, key->params_size);
+     key->pk_algorithm, &key->params);
 
   if (result < 0)
     {
@@ -992,24 +939,26 @@ gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t key,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
+  gnutls_pk_params_init(&key->params);
+
   siz = m->size;
-  if (_gnutls_mpi_scan_nz (&key->params[0], m->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz))
     {
       gnutls_assert ();
       return GNUTLS_E_MPI_SCAN_FAILED;
     }
 
   siz = e->size;
-  if (_gnutls_mpi_scan_nz (&key->params[1], e->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz))
     {
       gnutls_assert ();
-      _gnutls_mpi_release (&key->params[0]);
+      _gnutls_mpi_release (&key->params.params[0]);
       return GNUTLS_E_MPI_SCAN_FAILED;
     }
 
-  key->params_size = RSA_PUBLIC_PARAMS;
+  key->params.params_nr = RSA_PUBLIC_PARAMS;
   key->pk_algorithm = GNUTLS_PK_RSA;
-  key->bits = pubkey_to_bits(GNUTLS_PK_RSA, key->params, key->params_size);
+  key->bits = pubkey_to_bits(GNUTLS_PK_RSA, &key->params);
 
   return 0;
 }
@@ -1038,6 +987,8 @@ gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key,
 {
   size_t siz = 0;
 
+  gnutls_pk_params_init(&key->params);
+
   if (key == NULL)
     {
       gnutls_assert ();
@@ -1045,42 +996,42 @@ gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key,
     }
 
   siz = p->size;
-  if (_gnutls_mpi_scan_nz (&key->params[0], p->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz))
     {
       gnutls_assert ();
       return GNUTLS_E_MPI_SCAN_FAILED;
     }
 
   siz = q->size;
-  if (_gnutls_mpi_scan_nz (&key->params[1], q->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz))
     {
       gnutls_assert ();
-      _gnutls_mpi_release (&key->params[0]);
+      _gnutls_mpi_release (&key->params.params[0]);
       return GNUTLS_E_MPI_SCAN_FAILED;
     }
 
   siz = g->size;
-  if (_gnutls_mpi_scan_nz (&key->params[2], g->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz))
     {
       gnutls_assert ();
-      _gnutls_mpi_release (&key->params[1]);
-      _gnutls_mpi_release (&key->params[0]);
+      _gnutls_mpi_release (&key->params.params[1]);
+      _gnutls_mpi_release (&key->params.params[0]);
       return GNUTLS_E_MPI_SCAN_FAILED;
     }
 
   siz = y->size;
-  if (_gnutls_mpi_scan_nz (&key->params[3], y->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz))
     {
       gnutls_assert ();
-      _gnutls_mpi_release (&key->params[2]);
-      _gnutls_mpi_release (&key->params[1]);
-      _gnutls_mpi_release (&key->params[0]);
+      _gnutls_mpi_release (&key->params.params[2]);
+      _gnutls_mpi_release (&key->params.params[1]);
+      _gnutls_mpi_release (&key->params.params[0]);
       return GNUTLS_E_MPI_SCAN_FAILED;
     }
 
-  key->params_size = DSA_PUBLIC_PARAMS;
+  key->params.params_nr = DSA_PUBLIC_PARAMS;
   key->pk_algorithm = GNUTLS_PK_DSA;
-  key->bits = pubkey_to_bits(GNUTLS_PK_DSA, key->params, key->params_size);
+  key->bits = pubkey_to_bits(GNUTLS_PK_DSA, &key->params);
 
   return 0;
 
@@ -1116,7 +1067,7 @@ gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey, unsigned int flags,
     }
 
   ret = pubkey_verify_sig( data, NULL, signature, pubkey->pk_algorithm, 
-    pubkey->params, pubkey->params_size);
+    &pubkey->params);
   if (ret < 0)
     {
       gnutls_assert();
@@ -1151,12 +1102,11 @@ gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags,
     }
 
   if (flags & GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA)
-    return _gnutls_rsa_verify (hash, signature, key->params,
-                                     key->params_size, 1);
+    return _gnutls_rsa_verify (hash, signature, &key->params, 1);
   else
     {
       return pubkey_verify_sig (NULL, hash, signature, key->pk_algorithm,
-                       key->params, key->params_size);
+                       &key->params);
     }
 }
 
@@ -1186,7 +1136,7 @@ gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key,
   return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *)
                                         hash, signature,
                                         key->pk_algorithm,
-                                        key->params, key->params_size);
+                                        &key->params);
 
 }
 
@@ -1196,7 +1146,7 @@ int _gnutls_pubkey_compatible_with_sig(gnutls_pubkey_t pubkey, gnutls_protocol_t
 {
   if (pubkey->pk_algorithm == GNUTLS_PK_DSA)
     { /* override */
-      int hash_algo = _gnutls_dsa_q_to_hash (pubkey->params[1]);
+      int hash_algo = _gnutls_dsa_q_to_hash (pubkey->params.params[1]);
 
       /* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */
       if (!_gnutls_version_has_selectable_sighash (ver))
@@ -1218,27 +1168,18 @@ int _gnutls_pubkey_compatible_with_sig(gnutls_pubkey_t pubkey, gnutls_protocol_t
 /* Returns zero if the public key has more than 512 bits */
 int _gnutls_pubkey_is_over_rsa_512(gnutls_pubkey_t pubkey)
 {
-  if (pubkey->pk_algorithm == GNUTLS_PK_RSA && _gnutls_mpi_get_nbits (pubkey->params[0]) > 512)
+  if (pubkey->pk_algorithm == GNUTLS_PK_RSA && _gnutls_mpi_get_nbits (pubkey->params.params[0]) > 512)
     return 0;
   else
     return GNUTLS_E_INVALID_REQUEST; /* doesn't matter */
 
 }
 
-/* Returns the public key. The mpis are the internal copy. Should
- * not be deallocated.
+/* Returns the public key. 
  */
 int
 _gnutls_pubkey_get_mpis (gnutls_pubkey_t key,
-                                 bigint_t * params, int *params_size)
+                                 gnutls_pk_params_st * params)
 {
-  int i;
-
-  if (*params_size < key->params_size)
-    return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
-
-  for (i=0;i<key->params_size;i++)
-    params[i] = key->params[i];
-
-  return 0;
+  return _gnutls_pk_params_copy(params, &key->params);
 }
index e867927c566e2f9116725528460961600ddc3b6b..858e5a6d4a34041606fb448b724cf92a3d1da616 100644 (file)
@@ -37,7 +37,7 @@
 /* returns e and m, depends on the requested bits.
  * We only support limited key sizes.
  */
-const bigint_t *
+const gnutls_pk_params_st*
 _gnutls_rsa_params_to_mpi (gnutls_rsa_params_t rsa_params)
 {
   if (rsa_params == NULL)
@@ -45,7 +45,7 @@ _gnutls_rsa_params_to_mpi (gnutls_rsa_params_t rsa_params)
       return NULL;
     }
 
-  return rsa_params->params;
+  return &rsa_params->params;
 }
 
 /**
@@ -201,7 +201,7 @@ gnutls_rsa_params_export_pkcs1 (gnutls_rsa_params_t params,
 
 /**
  * gnutls_rsa_params_export_raw:
- * @params: a structure that holds the rsa parameters
+ * @rsa: a structure that holds the rsa parameters
  * @m: will hold the modulus
  * @e: will hold the public exponent
  * @d: will hold the private exponent
@@ -217,7 +217,7 @@ gnutls_rsa_params_export_pkcs1 (gnutls_rsa_params_t params,
  * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code.
  **/
 int
-gnutls_rsa_params_export_raw (gnutls_rsa_params_t params,
+gnutls_rsa_params_export_raw (gnutls_rsa_params_t rsa,
                               gnutls_datum_t * m, gnutls_datum_t * e,
                               gnutls_datum_t * d, gnutls_datum_t * p,
                               gnutls_datum_t * q, gnutls_datum_t * u,
@@ -225,7 +225,7 @@ gnutls_rsa_params_export_raw (gnutls_rsa_params_t params,
 {
   int ret;
 
-  ret = gnutls_x509_privkey_export_rsa_raw (params, m, e, d, p, q, u);
+  ret = gnutls_x509_privkey_export_rsa_raw (rsa, m, e, d, p, q, u);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -233,7 +233,7 @@ gnutls_rsa_params_export_raw (gnutls_rsa_params_t params,
     }
 
   if (bits)
-    *bits = _gnutls_mpi_get_nbits (params->params[3]);
+    *bits = _gnutls_mpi_get_nbits (rsa->params.params[3]);
 
   return 0;
 }
index d148a911c40e192fe95aad08e2d565c4f3a30716..fa64189868faacf7c085400a08e6833ade7ff26d 100644 (file)
@@ -23,5 +23,5 @@
  *
  */
 
-const bigint_t *_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t);
+const gnutls_pk_params_st *_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t);
 int _gnutls_peers_cert_less_512 (gnutls_session_t session);
index 1e35478f37596d5c0c083a933a4cf345306ca33e..1f2ac23ab3bf8aefc769fbd632b8d763fc271acc 100644 (file)
@@ -166,8 +166,8 @@ _gnutls_handshake_sign_data (gnutls_session_t session, gnutls_pcert_st* cert,
  * given data. The output will be allocated and be put in signature.
  */
 int
-_gnutls_soft_sign (gnutls_pk_algorithm_t algo, bigint_t * params,
-                   int params_size, const gnutls_datum_t * data,
+_gnutls_soft_sign (gnutls_pk_algorithm_t algo, gnutls_pk_params_st * params,
+                   const gnutls_datum_t * data,
                    gnutls_datum_t * signature)
 {
   int ret;
@@ -176,8 +176,7 @@ _gnutls_soft_sign (gnutls_pk_algorithm_t algo, bigint_t * params,
     {
     case GNUTLS_PK_RSA:
       /* encrypt */
-      if ((ret = _gnutls_pkcs1_rsa_encrypt (signature, data, params,
-                                            params_size, 1)) < 0)
+      if ((ret = _gnutls_pkcs1_rsa_encrypt (signature, data, params, 1)) < 0)
         {
           gnutls_assert ();
           return ret;
@@ -186,7 +185,7 @@ _gnutls_soft_sign (gnutls_pk_algorithm_t algo, bigint_t * params,
       break;
     case GNUTLS_PK_DSA:
       /* sign */
-      if ((ret = _gnutls_dsa_sign (signature, data, params, params_size)) < 0)
+      if ((ret = _gnutls_dsa_sign (signature, data, params)) < 0)
         {
           gnutls_assert ();
           return ret;
@@ -747,7 +746,7 @@ _gnutls_handshake_sign_cert_vrfy (gnutls_session_t session,
 
 int
 pk_hash_data (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
-              bigint_t * params,
+              gnutls_pk_params_st* params,
               const gnutls_datum_t * data, gnutls_datum_t * digest)
 {
   int ret;
@@ -757,7 +756,7 @@ pk_hash_data (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
     case GNUTLS_PK_RSA:
       break;
     case GNUTLS_PK_DSA:
-      if (params && hash != _gnutls_dsa_q_to_hash (params[1]))
+      if (params && hash != _gnutls_dsa_q_to_hash (params->params[1]))
         {
           gnutls_assert ();
           return GNUTLS_E_INVALID_REQUEST;
index 44bbce0d14012cb6bd35e1ba55294fcacd967bd6..3b6957ac5835e40c4f58525eb8b5c7332fda9c57 100644 (file)
@@ -52,14 +52,14 @@ int _gnutls_handshake_verify_data (gnutls_session_t session,
                                    gnutls_sign_algorithm_t algo);
 
 int _gnutls_soft_sign (gnutls_pk_algorithm_t algo,
-                       bigint_t * params, int params_size,
+                       gnutls_pk_params_st* params,
                        const gnutls_datum_t * data,
                        gnutls_datum_t * signature);
 
 int pk_prepare_hash (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
                      gnutls_datum_t * output);
 int pk_hash_data (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
-                  bigint_t * params, const gnutls_datum_t * data,
+                  gnutls_pk_params_st * params, const gnutls_datum_t * data,
                   gnutls_datum_t * digest);
 
 int
index 5cc09b5e49289e5787f97138b40576acbef6ca0e..0a4ee1d17a0905ac1c1cad974e7d153ecde5861b 100644 (file)
@@ -67,7 +67,7 @@ _gnutls_session_cert_type_set (gnutls_session_t session,
 
 void
 _gnutls_session_ecc_curve_set (gnutls_session_t session,
-                               ecc_curve_t c)
+                               gnutls_ecc_curve_t c)
 {
   _gnutls_handshake_log("HSK[%p]: Selected ECC curve (%d)\n", session, c);
   session->security_parameters.ecc_curve = c;
@@ -1188,6 +1188,9 @@ _gnutls_session_is_ecc (gnutls_session_t session)
 {
   gnutls_kx_algorithm_t kx;
 
+  /* We get the key exchange algorithm through the ciphersuite because
+   * the negotiated key exchange might not have been set yet.
+   */
   kx =
     _gnutls_cipher_suite_get_kx_algo (&session->
                                       security_parameters.current_cipher_suite);
index 7e51463d8e98609853b909281ddb154aa0c54ece..3266dd999d2f394ff7644d63f1761667099f195f 100644 (file)
@@ -31,7 +31,7 @@
 void _gnutls_session_cert_type_set (gnutls_session_t session,
                                     gnutls_certificate_type_t);
 
-inline static ecc_curve_t _gnutls_session_ecc_curve_get(gnutls_session_t session)
+inline static gnutls_ecc_curve_t _gnutls_session_ecc_curve_get(gnutls_session_t session)
 {
   return session->security_parameters.ecc_curve;
 }
@@ -40,7 +40,7 @@ int _gnutls_session_is_ecc (gnutls_session_t session);
 
 void
 _gnutls_session_ecc_curve_set (gnutls_session_t session,
-                               ecc_curve_t c);
+                               gnutls_ecc_curve_t c);
 
 void
 _gnutls_record_set_default_version (gnutls_session_t session,
index 4ff4510d9a54382c289018728222890d3cc24295..80fbf825d958146693e1b06e85d44550f51c4126 100644 (file)
@@ -279,7 +279,7 @@ extern "C"
  *  [3] is y (public key)
  *  [4] is x (private key only)
  *
- * ECDH:
+ * ECC:
  *  [0] is prime
  *  [1] is order
  *  [2] is A
index 18097cc22ff7b81d0c895cda90ed3ab2f4be4158..58e53cd54370240547dc68f8b777dbd5f0c8dfd8 100644 (file)
@@ -621,6 +621,25 @@ extern "C"
     GNUTLS_SIGN_ECDSA_SHA512 = 16,
   } gnutls_sign_algorithm_t;
 
+  /**
+   * gnutls_ecc_curve_t:
+   * @GNUTLS_ECC_CURVE_INVALID: Cannot be known
+   * @GNUTLS_ECC_CURVE_SECP224R1: the SECP224R1 curve
+   * @GNUTLS_ECC_CURVE_SECP256R1: the SECP256R1 curve
+   * @GNUTLS_ECC_CURVE_SECP384R1: the SECP384R1 curve
+   * @GNUTLS_ECC_CURVE_SECP521R1: the SECP521R1 curve
+   *
+   * Enumeration of ECC curves.
+   */
+typedef enum
+{
+  GNUTLS_ECC_CURVE_INVALID=0,
+  GNUTLS_ECC_CURVE_SECP224R1,
+  GNUTLS_ECC_CURVE_SECP256R1,
+  GNUTLS_ECC_CURVE_SECP384R1,
+  GNUTLS_ECC_CURVE_SECP521R1,
+} gnutls_ecc_curve_t;
+
   /**
    * gnutls_sec_param_t:
    * @GNUTLS_SEC_PARAM_UNKNOWN: Cannot be known
@@ -721,6 +740,10 @@ extern "C"
   unsigned int gnutls_sec_param_to_pk_bits (gnutls_pk_algorithm_t algo,
                                             gnutls_sec_param_t param);
 
+/* Elliptic curves */
+const char * gnutls_ecc_curve_get_name (gnutls_ecc_curve_t curve);
+int gnutls_ecc_curve_get_size (gnutls_ecc_curve_t curve);
+
 /* get information on the current session */
   gnutls_cipher_algorithm_t gnutls_cipher_get (gnutls_session_t session);
   gnutls_kx_algorithm_t gnutls_kx_get (gnutls_session_t session);
@@ -1772,6 +1795,7 @@ extern "C"
 #define GNUTLS_E_TIMEDOUT -319
 #define GNUTLS_E_USER_ERROR -320
 #define GNUTLS_E_ECC_NO_SUPPORTED_CURVES -321
+#define GNUTLS_E_ECC_UNSUPPORTED_CURVE -322
 
 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
 
index ccae4576a0186e9999d79754cc789ef4e336c892..1fe7dcfd9ca5b28c2a9116b842947616422ecdf8 100644 (file)
@@ -713,6 +713,8 @@ GNUTLS_3_0_0 {
        gnutls_certificate_set_retrieve_function2;
        gnutls_x509_trust_list_get_issuer;
        gnutls_global_set_audit_log_function;
+       gnutls_ecc_curve_get_name;
+       gnutls_ecc_curve_get_size;
 } GNUTLS_2_12;
 
 GNUTLS_PRIVATE {
index 5dc99b89ab2affed69e1f8e720e3f8e6c13a8661..30250faf3a9e8deba0fb228b3286772e657c1ff1 100644 (file)
@@ -54,7 +54,7 @@ ecc_test (void)
     {
       const gnutls_ecc_curve_entry_st *st = _gnutls_ecc_curve_get_params (i);
 
-      printf ("Testing %s (%d)\n", _gnutls_ecc_curve_get_name (i), i);
+      printf ("Testing %s (%d)\n", gnutls_ecc_curve_get_name (i), i);
 
       if (mpz_set_str (A, (char *) st->A, 16) != 0)
         {
index 3af3e2067885105a4669d50f4003de50e3b17534..971e6f0f0e80e6a5a2b0338e8063899f4a62f6e4 100644 (file)
@@ -555,7 +555,7 @@ cleanup:
 
 static inline int is_supported_curve(int curve)
 {
-  if (_gnutls_ecc_curve_get_name(curve) != NULL)
+  if (gnutls_ecc_curve_get_name(curve) != NULL)
     return 1;
   else
     return 0;
@@ -703,7 +703,7 @@ rsa_fail:
           return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
 
         params->params_nr = 0;
-        for (i = 0; i < ECDH_PRIVATE_PARAMS; i++)
+        for (i = 0; i < ECC_PRIVATE_PARAMS; i++)
           {
             params->params[i] = _gnutls_mpi_alloc_like(&key.prime);
             if (params->params[i] == NULL)
@@ -773,7 +773,7 @@ wrap_nettle_pk_fixup (gnutls_pk_algorithm_t algo,
       _gnutls_mpi_release (&params->params[6]);
       _gnutls_mpi_release (&params->params[7]);
 
-      result = _gnutls_calc_rsa_exp (params->params, RSA_PRIVATE_PARAMS - 2);
+      result = _gnutls_calc_rsa_exp (params);
       if (result < 0)
         {
           gnutls_assert ();
index 7ad6d297ce423113848a44d33bb91617e79cedef..9a17b049b367d4daac2db51f6ed26a6068491a05 100644 (file)
@@ -49,12 +49,11 @@ unsigned int _gnutls_get_pgp_key_usage (unsigned int pgp_usage);
 
 int
 _gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert, uint32_t keyid[2],
-                              bigint_t * params, int *params_size);
+                              gnutls_pk_params_st * params);
 
 int
 _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey,
-                                  uint32_t keyid[2], bigint_t * params,
-                                  int *params_size);
+                                  uint32_t keyid[2], gnutls_pk_params_st* params);
 
 cdk_packet_t _gnutls_openpgp_find_key (cdk_kbnode_t knode, uint32_t keyid[2],
                                        unsigned int priv);
index 9630448bedd7f45c9baf4c6f59a8c9c085e4b3a3..45b93ffe777febe0d5b802dce619b40e2709e5c4 100644 (file)
@@ -1187,7 +1187,7 @@ _gnutls_read_pgp_mpi (cdk_packet_t pkt, unsigned int priv, size_t idx,
 int
 _gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert,
                               uint32_t * keyid /* [2] */ ,
-                              bigint_t * params, int *params_size)
+                              gnutls_pk_params_st * params)
 {
   int result, i;
   int pk_algorithm, local_params;
@@ -1219,32 +1219,23 @@ _gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert,
       return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
     }
 
-  if (*params_size < local_params)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
-    }
-
-  *params_size = local_params;
+  gnutls_pk_params_init(params);
 
   for (i = 0; i < local_params; i++)
     {
-      result = _gnutls_read_pgp_mpi (pkt, 0, i, &params[i]);
+      result = _gnutls_read_pgp_mpi (pkt, 0, i, &params->params[i]);
       if (result < 0)
         {
           gnutls_assert ();
           goto error;
         }
+      params->params_nr++;
     }
 
   return 0;
 
 error:
-  {
-    int j;
-    for (j = 0; j < i; j++)
-      _gnutls_mpi_release (&params[j]);
-  }
+  gnutls_pk_params_release(params);
 
   return result;
 }
@@ -1255,11 +1246,12 @@ static int
 _get_pk_rsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid,
                  gnutls_datum_t * m, gnutls_datum_t * e)
 {
-  int pk_algorithm, ret, i;
+  int pk_algorithm, ret;
   cdk_packet_t pkt;
   uint32_t kid32[2];
-  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
-  int params_size = MAX_PUBLIC_PARAMS_SIZE;
+  gnutls_pk_params_st params;
+
+  gnutls_pk_params_init(&params);
 
   if (crt == NULL)
     {
@@ -1284,21 +1276,21 @@ _get_pk_rsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  ret = _gnutls_openpgp_crt_get_mpis (crt, kid32, params, &params_size);
+  ret = _gnutls_openpgp_crt_get_mpis (crt, kid32, &params);
   if (ret < 0)
     {
       gnutls_assert ();
       return ret;
     }
 
-  ret = _gnutls_mpi_dprint (params[0], m);
+  ret = _gnutls_mpi_dprint (params.params[0], m);
   if (ret < 0)
     {
       gnutls_assert ();
       goto cleanup;
     }
 
-  ret = _gnutls_mpi_dprint (params[1], e);
+  ret = _gnutls_mpi_dprint (params.params[1], e);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1309,10 +1301,7 @@ _get_pk_rsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid,
   ret = 0;
 
 cleanup:
-  for (i = 0; i < params_size; i++)
-    {
-      _gnutls_mpi_release (&params[i]);
-    }
+  gnutls_pk_params_release(&params);
   return ret;
 }
 
@@ -1321,11 +1310,12 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid,
                  gnutls_datum_t * p, gnutls_datum_t * q,
                  gnutls_datum_t * g, gnutls_datum_t * y)
 {
-  int pk_algorithm, ret, i;
+  int pk_algorithm, ret;
   cdk_packet_t pkt;
   uint32_t kid32[2];
-  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
-  int params_size = MAX_PUBLIC_PARAMS_SIZE;
+  gnutls_pk_params_st params;
+  
+  gnutls_pk_params_init(&params);
 
   if (crt == NULL)
     {
@@ -1350,7 +1340,7 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  ret = _gnutls_openpgp_crt_get_mpis (crt, kid32, params, &params_size);
+  ret = _gnutls_openpgp_crt_get_mpis (crt, kid32, &params);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1358,7 +1348,7 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid,
     }
 
   /* P */
-  ret = _gnutls_mpi_dprint (params[0], p);
+  ret = _gnutls_mpi_dprint (params.params[0], p);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1366,7 +1356,7 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid,
     }
 
   /* Q */
-  ret = _gnutls_mpi_dprint (params[1], q);
+  ret = _gnutls_mpi_dprint (params.params[1], q);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1376,7 +1366,7 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid,
 
 
   /* G */
-  ret = _gnutls_mpi_dprint (params[2], g);
+  ret = _gnutls_mpi_dprint (params.params[2], g);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1387,7 +1377,7 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid,
 
 
   /* Y */
-  ret = _gnutls_mpi_dprint (params[3], y);
+  ret = _gnutls_mpi_dprint (params.params[3], y);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1400,10 +1390,7 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid,
   ret = 0;
 
 cleanup:
-  for (i = 0; i < params_size; i++)
-    {
-      _gnutls_mpi_release (&params[i]);
-    }
+  gnutls_pk_params_release(&params);
   return ret;
 }
 
index 2d0a39c45a7d5a6f13a7d53982aa40bd2b79ad74..d596637496907822cf7aa844b2c0704546cc1939 100644 (file)
@@ -712,14 +712,13 @@ gnutls_openpgp_privkey_get_subkey_fingerprint (gnutls_openpgp_privkey_t key,
 int
 _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey,
                                   uint32_t * keyid /*[2] */ ,
-                                  bigint_t * params, int *params_size)
+                                  gnutls_pk_params_st * params)
 {
   int result, i;
   int pk_algorithm;
-  gnutls_pk_params_st pk_params;
   cdk_packet_t pkt;
 
-  memset (&pk_params, 0, sizeof (pk_params));
+  gnutls_pk_params_init(params);
 
   if (keyid == NULL)
     pkt = cdk_kbnode_find_packet (pkey->knode, CDK_PKT_SECRET_KEY);
@@ -740,19 +739,19 @@ _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey,
     case GNUTLS_PK_RSA:
       /* openpgp does not hold all parameters as in PKCS #1
        */
-      pk_params.params_nr = RSA_PRIVATE_PARAMS - 2;
+      params->params_nr = RSA_PRIVATE_PARAMS - 2;
       break;
     case GNUTLS_PK_DSA:
-      pk_params.params_nr = DSA_PRIVATE_PARAMS;
+      params->params_nr = DSA_PRIVATE_PARAMS;
       break;
     default:
       gnutls_assert ();
       return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
     }
 
-  for (i = 0; i < pk_params.params_nr; i++)
+  for (i = 0; i < params->params_nr; i++)
     {
-      result = _gnutls_read_pgp_mpi (pkt, 1, i, &pk_params.params[i]);
+      result = _gnutls_read_pgp_mpi (pkt, 1, i, &params->params[i]);
       if (result < 0)
         {
           gnutls_assert ();
@@ -763,31 +762,17 @@ _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey,
   /* fixup will generate exp1 and exp2 that are not
    * available here.
    */
-  result = _gnutls_pk_fixup (pk_algorithm, GNUTLS_IMPORT, &pk_params);
+  result = _gnutls_pk_fixup (pk_algorithm, GNUTLS_IMPORT, params);
   if (result < 0)
     {
       gnutls_assert ();
       goto error;
     }
 
-  if (*params_size < pk_params.params_nr)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
-    }
-
-  *params_size = pk_params.params_nr;
-  for (i = 0; i < pk_params.params_nr; i++)
-    params[i] = pk_params.params[i];
-
   return 0;
 
 error:
-  {
-    int j;
-    for (j = 0; j < i; j++)
-      _gnutls_mpi_release (&pk_params.params[j]);
-  }
+  gnutls_pk_params_release(params);
 
   return result;
 }
@@ -800,11 +785,10 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
                  gnutls_datum_t * d, gnutls_datum_t * p,
                  gnutls_datum_t * q, gnutls_datum_t * u)
 {
-  int pk_algorithm, ret, i;
+  int pk_algorithm, ret;
   cdk_packet_t pkt;
   uint32_t kid32[2];
-  bigint_t params[MAX_PRIV_PARAMS_SIZE];
-  int params_size = MAX_PRIV_PARAMS_SIZE;
+  gnutls_pk_params_st params;
 
   if (pkey == NULL)
     {
@@ -830,21 +814,21 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, params, &params_size);
+  ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, &params);
   if (ret < 0)
     {
       gnutls_assert ();
       return ret;
     }
 
-  ret = _gnutls_mpi_dprint (params[0], m);
+  ret = _gnutls_mpi_dprint (params.params[0], m);
   if (ret < 0)
     {
       gnutls_assert ();
       goto cleanup;
     }
 
-  ret = _gnutls_mpi_dprint (params[1], e);
+  ret = _gnutls_mpi_dprint (params.params[1], e);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -852,7 +836,7 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
       goto cleanup;
     }
 
-  ret = _gnutls_mpi_dprint (params[2], d);
+  ret = _gnutls_mpi_dprint (params.params[2], d);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -861,7 +845,7 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
       goto cleanup;
     }
 
-  ret = _gnutls_mpi_dprint (params[3], p);
+  ret = _gnutls_mpi_dprint (params.params[3], p);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -871,7 +855,7 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
       goto cleanup;
     }
 
-  ret = _gnutls_mpi_dprint (params[4], q);
+  ret = _gnutls_mpi_dprint (params.params[4], q);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -882,7 +866,7 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
       goto cleanup;
     }
 
-  ret = _gnutls_mpi_dprint (params[5], u);
+  ret = _gnutls_mpi_dprint (params.params[5], u);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -897,10 +881,7 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
   ret = 0;
 
 cleanup:
-  for (i = 0; i < params_size; i++)
-    {
-      _gnutls_mpi_release (&params[i]);
-    }
+  gnutls_pk_params_release(&params);
   return ret;
 }
 
@@ -909,11 +890,10 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
                  gnutls_datum_t * p, gnutls_datum_t * q,
                  gnutls_datum_t * g, gnutls_datum_t * y, gnutls_datum_t * x)
 {
-  int pk_algorithm, ret, i;
+  int pk_algorithm, ret;
   cdk_packet_t pkt;
   uint32_t kid32[2];
-  bigint_t params[MAX_PRIV_PARAMS_SIZE];
-  int params_size = MAX_PRIV_PARAMS_SIZE;
+  gnutls_pk_params_st params;
 
   if (pkey == NULL)
     {
@@ -939,7 +919,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, params, &params_size);
+  ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, &params);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -947,7 +927,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
     }
 
   /* P */
-  ret = _gnutls_mpi_dprint (params[0], p);
+  ret = _gnutls_mpi_dprint (params.params[0], p);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -955,7 +935,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
     }
 
   /* Q */
-  ret = _gnutls_mpi_dprint (params[1], q);
+  ret = _gnutls_mpi_dprint (params.params[1], q);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -965,7 +945,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
 
 
   /* G */
-  ret = _gnutls_mpi_dprint (params[2], g);
+  ret = _gnutls_mpi_dprint (params.params[2], g);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -976,7 +956,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
 
 
   /* Y */
-  ret = _gnutls_mpi_dprint (params[3], y);
+  ret = _gnutls_mpi_dprint (params.params[3], y);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -986,7 +966,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
       goto cleanup;
     }
 
-  ret = _gnutls_mpi_dprint (params[4], x);
+  ret = _gnutls_mpi_dprint (params.params[4], x);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1000,10 +980,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
   ret = 0;
 
 cleanup:
-  for (i = 0; i < params_size; i++)
-    {
-      _gnutls_mpi_release (&params[i]);
-    }
+  gnutls_pk_params_release(&params);
   return ret;
 }
 
@@ -1249,9 +1226,8 @@ gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
                                    const gnutls_datum_t * hash,
                                    gnutls_datum_t * signature)
 {
-  int result, i;
-  bigint_t params[MAX_PRIV_PARAMS_SIZE];
-  int params_size = MAX_PRIV_PARAMS_SIZE;
+  int result;
+  gnutls_pk_params_st params;
   int pk_algorithm;
   uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
 
@@ -1273,13 +1249,12 @@ gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
       pk_algorithm =
         gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL);
       result =
-        _gnutls_openpgp_privkey_get_mpis (key, kid, params, &params_size);
+        _gnutls_openpgp_privkey_get_mpis (key, kid, &params);
     }
   else
     {
       pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
-      result = _gnutls_openpgp_privkey_get_mpis (key, NULL,
-                                                 params, &params_size);
+      result = _gnutls_openpgp_privkey_get_mpis (key, NULL, &params);
     }
 
   if (result < 0)
@@ -1290,10 +1265,9 @@ gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
 
 
   result =
-    _gnutls_soft_sign (pk_algorithm, params, params_size, hash, signature);
+    _gnutls_soft_sign (pk_algorithm, &params, hash, signature);
 
-  for (i = 0; i < params_size; i++)
-    _gnutls_mpi_release (&params[i]);
+  gnutls_pk_params_release(&params);
 
   if (result < 0)
     {
@@ -1325,8 +1299,7 @@ _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key,
                                      gnutls_datum_t * plaintext)
 {
   int result, i;
-  bigint_t params[MAX_PRIV_PARAMS_SIZE];
-  int params_size = MAX_PRIV_PARAMS_SIZE;
+  gnutls_pk_params_st params;
   int pk_algorithm;
   uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
 
@@ -1342,8 +1315,7 @@ _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key,
       uint32_t kid[2];
 
       KEYID_IMPORT (kid, keyid);
-      result = _gnutls_openpgp_privkey_get_mpis (key, kid,
-                                                 params, &params_size);
+      result = _gnutls_openpgp_privkey_get_mpis (key, kid, &params);
 
       i = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
 
@@ -1353,8 +1325,7 @@ _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key,
     {
       pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
 
-      result = _gnutls_openpgp_privkey_get_mpis (key, NULL,
-                                                 params, &params_size);
+      result = _gnutls_openpgp_privkey_get_mpis (key, NULL, &params);
 
     }
 
@@ -1371,10 +1342,9 @@ _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key,
     }
 
   result =
-    _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext, params, params_size, 2);
+    _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext, &params, 2);
 
-  for (i = 0; i < params_size; i++)
-    _gnutls_mpi_release (&params[i]);
+  gnutls_pk_params_release(&params);
 
   if (result < 0)
     {
index 7b022bf765648a665d46196ea377e633a57fbd65..4af52a1649f4db1bfabad20abe83e2a1075ccc90 100644 (file)
@@ -34,8 +34,8 @@ endif
 noinst_LTLIBRARIES = libgnutls_x509.la
 
 libgnutls_x509_la_SOURCES =    \
-       common.c                \
-       common.h                \
+       common.c key_encode.c   \
+       common.h key_decode.c   \
        crl.c                   \
        crl_write.c             \
        crq.c                   \
index 6b76d28b00cac4596bff49e1144e5dd8bf29f769..9bbfd387bcfcb9e5c90898bb3d1c8a1f644db158 100644 (file)
@@ -1183,8 +1183,7 @@ int
 _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
                                          const char *dst_name,
                                          gnutls_pk_algorithm_t
-                                         pk_algorithm, bigint_t * params,
-                                         int params_size)
+                                         pk_algorithm, gnutls_pk_params_st * params)
 {
   const char *pk;
   gnutls_datum_t der = { NULL, 0 };
@@ -1209,87 +1208,45 @@ _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
       return _gnutls_asn2err (result);
     }
 
-  if (pk_algorithm == GNUTLS_PK_RSA)
+  result = _gnutls_x509_write_pubkey_params (pk_algorithm, params, &der);
+  if (result < 0)
     {
-      /* disable parameters, which are not used in RSA.
-       */
-      _asnstr_append_name (name, sizeof (name), dst_name,
-                           ".algorithm.parameters");
-
-      result = asn1_write_value (dst, name, ASN1_NULL, ASN1_NULL_SIZE);
-      if (result != ASN1_SUCCESS)
-        {
-          gnutls_assert ();
-          return _gnutls_asn2err (result);
-        }
-
-      result = _gnutls_x509_write_rsa_params (params, params_size, &der);
-      if (result < 0)
-        {
-          gnutls_assert ();
-          return result;
-        }
-
-      /* Write the DER parameters. (in bits)
-       */
-      _asnstr_append_name (name, sizeof (name), dst_name,
-                           ".subjectPublicKey");
-      result = asn1_write_value (dst, name, der.data, der.size * 8);
-
-      _gnutls_free_datum (&der);
-
-      if (result != ASN1_SUCCESS)
-        {
-          gnutls_assert ();
-          return _gnutls_asn2err (result);
-        }
+      gnutls_assert ();
+      return result;
     }
-  else if (pk_algorithm == GNUTLS_PK_DSA)
-    {
 
-      result = _gnutls_x509_write_dsa_params (params, params_size, &der);
-      if (result < 0)
-        {
-          gnutls_assert ();
-          return result;
-        }
+  _asnstr_append_name (name, sizeof (name), dst_name,
+                       ".algorithm.parameters");
 
-      /* Write the DER parameters.
-       */
-      _asnstr_append_name (name, sizeof (name), dst_name,
-                           ".algorithm.parameters");
-      result = asn1_write_value (dst, name, der.data, der.size);
+  result = asn1_write_value (dst, name, der.data, der.size);
 
-      _gnutls_free_datum (&der);
-
-      if (result != ASN1_SUCCESS)
-        {
-          gnutls_assert ();
-          return _gnutls_asn2err (result);
-        }
-
-      result = _gnutls_x509_write_dsa_public_key (params, params_size, &der);
-      if (result < 0)
-        {
-          gnutls_assert ();
-          return result;
-        }
+  _gnutls_free_datum (&der);
 
-      _asnstr_append_name (name, sizeof (name), dst_name,
-                           ".subjectPublicKey");
-      result = asn1_write_value (dst, name, der.data, der.size * 8);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
 
-      _gnutls_free_datum (&der);
+  result = _gnutls_x509_write_pubkey (pk_algorithm, params, &der);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
 
-      if (result != ASN1_SUCCESS)
-        {
-          gnutls_assert ();
-          return _gnutls_asn2err (result);
-        }
+  /* Write the DER parameters. (in bits)
+   */
+  _asnstr_append_name (name, sizeof (name), dst_name,
+                       ".subjectPublicKey");
+  result = asn1_write_value (dst, name, der.data, der.size * 8);
+  _gnutls_free_datum (&der);
 
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
     }
-  else
-    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
 
   return 0;
 }
@@ -1306,9 +1263,10 @@ _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
   int algo;
   char oid[64];
   int len;
-  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
+  gnutls_pk_params_st params;
   char name[128];
 
+  gnutls_pk_params_init(&params);
 
   _asnstr_append_name (name, sizeof (name), src_name, ".algorithm.algorithm");
   len = sizeof (oid);
@@ -1372,38 +1330,13 @@ _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
 
   len /= 8;
 
-  switch (algo)
-    {
-    case GNUTLS_PK_RSA:
-      {
-        if ((result = _gnutls_x509_read_rsa_params (str, len, params)) < 0)
-          {
-            gnutls_assert ();
-            return result;
-          }
-
-        bits[0] = _gnutls_mpi_get_nbits (params[0]);
-
-        _gnutls_mpi_release (&params[0]);
-        _gnutls_mpi_release (&params[1]);
-      }
-      break;
-    case GNUTLS_PK_DSA:
-      {
-
-        if ((result = _gnutls_x509_read_dsa_pubkey (str, len, params)) < 0)
-          {
-            gnutls_assert ();
-            return result;
-          }
-
-        bits[0] = _gnutls_mpi_get_nbits (params[3]);
-
-        _gnutls_mpi_release (&params[3]);
-      }
-      break;
-    }
+  result = _gnutls_x509_read_pubkey (algo, str, len, &params);
+  if (result < 0)
+    return gnutls_assert_val(result);
+  bits[0] = pubkey_to_bits(algo, &params);
 
+  gnutls_pk_params_release(&params);
   gnutls_free (str);
   return algo;
 }
index 0368e5acec98cdbcad556b1b1b704c17208d04b8..86e6b8dfa0f6669391dac55e54d6ff52656cf5ed 100644 (file)
@@ -27,6 +27,7 @@
 #define COMMON_H
 
 #include <algorithms.h>
+#include <abstract_int.h>
 #include <x509/x509_int.h>
 
 #define MAX_STRING_LEN 512
@@ -130,8 +131,7 @@ int _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
 int _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
                                              const char *dst_name,
                                              gnutls_pk_algorithm_t
-                                             pk_algorithm, bigint_t * params,
-                                             int params_size);
+                                             pk_algorithm, gnutls_pk_params_st * params);
 int _gnutls_asn1_copy_node (ASN1_TYPE * dst, const char *dst_name,
                             ASN1_TYPE src, const char *src_name);
 
@@ -143,10 +143,10 @@ int _gnutls_x509_get_signature (ASN1_TYPE src, const char *src_name,
 gnutls_digest_algorithm_t _gnutls_dsa_q_to_hash (bigint_t q);
 
 int _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root,
-                          bigint_t * params, int *params_size);
+                          gnutls_pk_params_st * params);
 
-int _gnutls_get_key_id (gnutls_pk_algorithm_t pk, bigint_t * params,
-                        int params_size, unsigned char *output_data,
+int _gnutls_get_key_id (gnutls_pk_algorithm_t pk, gnutls_pk_params_st*,
+                        unsigned char *output_data,
                         size_t * output_data_size);
 
 void _asnstr_append_name (char *name, size_t name_size, const char *part1,
@@ -155,8 +155,8 @@ void _asnstr_append_name (char *name, size_t name_size, const char *part1,
 int pubkey_verify_sig (const gnutls_datum_t * tbs,
                        const gnutls_datum_t * hash,
                        const gnutls_datum_t * signature,
-                       gnutls_pk_algorithm_t pk, bigint_t * issuer_params,
-                       int issuer_params_size);
+                       gnutls_pk_algorithm_t pk, 
+                       gnutls_pk_params_st * issuer_params);
 
 int
 check_if_same_cert (gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2);
index 6cd0c96df901308b443f551be182dae53ed42658..c61b3c4043a8017f608224f8a2f72f5612100955 100644 (file)
@@ -792,7 +792,7 @@ gnutls_x509_crq_set_key (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
   result = _gnutls_x509_encode_and_copy_PKI_params
     (crq->crq,
      "certificationRequestInfo.subjectPKInfo",
-     key->pk_algorithm, key->params, key->params_size);
+     key->pk_algorithm, &key->params);
 
   if (result < 0)
     {
@@ -823,9 +823,9 @@ gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq,
                                  gnutls_datum_t * m, gnutls_datum_t * e)
 {
   int ret;
-  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
-  int params_size = MAX_PUBLIC_PARAMS_SIZE;
-  int i;
+  gnutls_pk_params_st params;
+
+  gnutls_pk_params_init(&params);
 
   if (crq == NULL)
     {
@@ -840,21 +840,21 @@ gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  ret = _gnutls_x509_crq_get_mpis (crq, params, &params_size);
+  ret = _gnutls_x509_crq_get_mpis (crq, &params);
   if (ret < 0)
     {
       gnutls_assert ();
       return ret;
     }
 
-  ret = _gnutls_mpi_dprint (params[0], m);
+  ret = _gnutls_mpi_dprint (params.params[0], m);
   if (ret < 0)
     {
       gnutls_assert ();
       goto cleanup;
     }
 
-  ret = _gnutls_mpi_dprint (params[1], e);
+  ret = _gnutls_mpi_dprint (params.params[1], e);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -865,10 +865,7 @@ gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq,
   ret = 0;
 
 cleanup:
-  for (i = 0; i < params_size; i++)
-    {
-      _gnutls_mpi_release (&params[i]);
-    }
+  gnutls_pk_params_release(&params);
   return ret;
 }
 
@@ -893,7 +890,9 @@ gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq,
 {
   int result, ret;
   size_t siz = 0;
-  bigint_t temp_params[RSA_PUBLIC_PARAMS];
+  gnutls_pk_params_st temp_params;
+
+  gnutls_pk_params_init(&temp_params);
 
   if (crq == NULL)
     {
@@ -901,10 +900,10 @@ gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  memset (temp_params, 0, sizeof (temp_params));
+  memset (&temp_params, 0, sizeof (temp_params));
 
   siz = m->size;
-  if (_gnutls_mpi_scan_nz (&temp_params[0], m->data, siz))
+  if (_gnutls_mpi_scan_nz (&temp_params.params[0], m->data, siz))
     {
       gnutls_assert ();
       ret = GNUTLS_E_MPI_SCAN_FAILED;
@@ -912,17 +911,19 @@ gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq,
     }
 
   siz = e->size;
-  if (_gnutls_mpi_scan_nz (&temp_params[1], e->data, siz))
+  if (_gnutls_mpi_scan_nz (&temp_params.params[1], e->data, siz))
     {
       gnutls_assert ();
       ret = GNUTLS_E_MPI_SCAN_FAILED;
       goto error;
     }
 
+  temp_params.params_nr = RSA_PUBLIC_PARAMS;
+
   result = _gnutls_x509_encode_and_copy_PKI_params
     (crq->crq,
      "certificationRequestInfo.subjectPKInfo",
-     GNUTLS_PK_RSA, temp_params, RSA_PUBLIC_PARAMS);
+     GNUTLS_PK_RSA, &temp_params);
 
   if (result < 0)
     {
@@ -934,8 +935,7 @@ gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq,
   ret = 0;
 
 error:
-  _gnutls_mpi_release (&temp_params[0]);
-  _gnutls_mpi_release (&temp_params[1]);
+  gnutls_pk_params_release(&temp_params);
   return ret;
 }
 
@@ -2271,39 +2271,26 @@ static int
 rsadsa_crq_get_key_id (gnutls_x509_crq_t crq, int pk,
                        unsigned char *output_data, size_t * output_data_size)
 {
-  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
-  int params_size = MAX_PUBLIC_PARAMS_SIZE;
-  int i, result = 0;
+  gnutls_pk_params_st params;
+  int result = 0;
   gnutls_datum_t der = { NULL, 0 };
   digest_hd_st hd;
 
-  result = _gnutls_x509_crq_get_mpis (crq, params, &params_size);
+  gnutls_pk_params_init(&params);
+
+  result = _gnutls_x509_crq_get_mpis (crq, &params);
   if (result < 0)
     {
       gnutls_assert ();
       return result;
     }
 
-  if (pk == GNUTLS_PK_RSA)
-    {
-      result = _gnutls_x509_write_rsa_params (params, params_size, &der);
-      if (result < 0)
-        {
-          gnutls_assert ();
-          goto cleanup;
-        }
-    }
-  else if (pk == GNUTLS_PK_DSA)
+  result = _gnutls_x509_write_pubkey( pk, &params, &der);
+  if (result < 0)
     {
-      result = _gnutls_x509_write_dsa_public_key (params, params_size, &der);
-      if (result < 0)
-        {
-          gnutls_assert ();
-          goto cleanup;
-        }
+      gnutls_assert ();
+      goto cleanup;
     }
-  else
-    return GNUTLS_E_INTERNAL_ERROR;
 
   result = _gnutls_hash_init (&hd, GNUTLS_MAC_SHA1);
   if (result < 0)
@@ -2325,10 +2312,7 @@ cleanup:
 
   /* release all allocated MPIs
    */
-  for (i = 0; i < params_size; i++)
-    {
-      _gnutls_mpi_release (&params[i]);
-    }
+  gnutls_pk_params_release(&params);
   return result;
 }
 
@@ -2538,8 +2522,10 @@ gnutls_x509_crq_verify (gnutls_x509_crq_t crq,
 {
 gnutls_datum data = { NULL, 0 };
 gnutls_datum signature = { NULL, 0 };
-bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
-int ret, params_size = 0, i;
+gnutls_pk_params_st params;
+int ret;
+
+  gnutls_pk_params_init(&params);
 
   ret =
     _gnutls_x509_get_signed_data (crq->crq, "certificationRequestInfo", &data);
@@ -2556,9 +2542,8 @@ int ret, params_size = 0, i;
       goto cleanup;
     }
 
-  params_size = MAX_PUBLIC_PARAMS_SIZE;
   ret =
-    _gnutls_x509_crq_get_mpis(crq, params, &params_size);
+    _gnutls_x509_crq_get_mpis(crq, &params);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -2567,7 +2552,7 @@ int ret, params_size = 0, i;
 
   ret = pubkey_verify_sig(&data, NULL, &signature,
                           gnutls_x509_crq_get_pk_algorithm (crq, NULL),
-                          params, params_size);
+                          &params);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -2579,11 +2564,7 @@ int ret, params_size = 0, i;
 cleanup:
   _gnutls_free_datum (&data);
   _gnutls_free_datum (&signature);
-
-  for (i = 0; i < params_size; i++)
-    {
-      _gnutls_mpi_release (&params[i]);
-    }
+  gnutls_pk_params_release(&params);
 
   return ret;
 }
diff --git a/lib/x509/key_decode.c b/lib/x509/key_decode.c
new file mode 100644 (file)
index 0000000..e2b56b5
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
+ *
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_errors.h>
+#include <gnutls_global.h>
+#include <libtasn1.h>
+#include <gnutls_datum.h>
+#include "common.h"
+#include "x509_int.h"
+#include <gnutls_num.h>
+#include <gnutls_ecc.h>
+
+static int _gnutls_x509_read_rsa_pubkey (opaque * der, int dersize,
+                                  gnutls_pk_params_st* params);
+static int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize,
+                                  gnutls_pk_params_st * params);
+static int _gnutls_x509_read_ecc_pubkey (opaque * der, int dersize,
+                                  gnutls_pk_params_st * params);
+
+static int
+_gnutls_x509_read_dsa_params (opaque * der, int dersize, gnutls_pk_params_st * params);
+
+static int
+_gnutls_x509_read_ecc_params (opaque * der, int dersize, gnutls_pk_params_st * params);
+
+/*
+ * some x509 certificate parsing functions that relate to MPI parameter
+ * extraction. This reads the BIT STRING subjectPublicKey.
+ * Returns 2 parameters (m,e). It does not set params_nr.
+ */
+int
+_gnutls_x509_read_rsa_pubkey (opaque * der, int dersize, gnutls_pk_params_st * params)
+{
+  int result;
+  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+
+  if ((result = asn1_create_element
+       (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk))
+      != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_der_decoding (&spk, der, dersize, NULL);
+
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&spk);
+      return _gnutls_asn2err (result);
+    }
+
+
+  if ((result = _gnutls_x509_read_int (spk, "modulus", &params->params[0])) < 0)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&spk);
+      return GNUTLS_E_ASN1_GENERIC_ERROR;
+    }
+
+  if ((result = _gnutls_x509_read_int (spk, "publicExponent",
+                                       &params->params[1])) < 0)
+    {
+      gnutls_assert ();
+      _gnutls_mpi_release (&params->params[0]);
+      asn1_delete_structure (&spk);
+      return GNUTLS_E_ASN1_GENERIC_ERROR;
+    }
+
+  asn1_delete_structure (&spk);
+
+  return 0;
+
+}
+
+/*
+ * some x509 certificate parsing functions that relate to MPI parameter
+ * extraction. This reads the BIT STRING subjectPublicKey.
+ * Returns 2 parameters (m,e). It does not set params_nr.
+ */
+int
+_gnutls_x509_read_ecc_pubkey (opaque * der, int dersize, gnutls_pk_params_st * params)
+{
+  uint8_t* octet;
+  int ret;
+  size_t octet_size = dersize;
+  
+  octet = gnutls_malloc(octet_size);
+  if (octet == NULL)
+    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+    
+  ret  = _gnutls_x509_decode_octet_string (NULL, der, dersize, octet, &octet_size);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+
+  ret = _gnutls_ecc_ansi_x963_import (octet, octet_size, &params->params[5],
+                                     &params->params[6]);
+  gnutls_free(octet);
+  
+  return ret;
+}
+
+
+/* reads p,q and g 
+ * from the certificate (subjectPublicKey BIT STRING).
+ * params[0-2]. It does NOT set params_nr.
+ */
+static int
+_gnutls_x509_read_dsa_params (opaque * der, int dersize, gnutls_pk_params_st * params)
+{
+  int result;
+  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+  
+  if ((result = asn1_create_element
+       (_gnutls_get_pkix (), "PKIX1.Dss-Parms", &spk)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_der_decoding (&spk, der, dersize, NULL);
+
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&spk);
+      return _gnutls_asn2err (result);
+    }
+
+  /* FIXME: If the parameters are not included in the certificate
+   * then the issuer's parameters should be used. This is not
+   * done yet.
+   */
+
+  /* Read p */
+
+  if ((result = _gnutls_x509_read_int (spk, "p", &params->params[0])) < 0)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&spk);
+      return GNUTLS_E_ASN1_GENERIC_ERROR;
+    }
+
+  /* Read q */
+
+  if ((result = _gnutls_x509_read_int (spk, "q", &params->params[1])) < 0)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&spk);
+      _gnutls_mpi_release (&params->params[0]);
+      return GNUTLS_E_ASN1_GENERIC_ERROR;
+    }
+
+  /* Read g */
+
+  if ((result = _gnutls_x509_read_int (spk, "g", &params->params[2])) < 0)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&spk);
+      _gnutls_mpi_release (&params->params[0]);
+      _gnutls_mpi_release (&params->params[1]);
+      return GNUTLS_E_ASN1_GENERIC_ERROR;
+    }
+
+  asn1_delete_structure (&spk);
+
+  return 0;
+
+}
+
+/* reads the curve from the certificate.
+ * params[0-4]. It does NOT set params_nr.
+ */
+static int
+_gnutls_x509_read_ecc_params (opaque * der, int dersize, gnutls_pk_params_st * params)
+{
+  int ret;
+  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+  char oid[MAX_OID_SIZE];
+  unsigned int oid_size;
+  
+  if ((ret = asn1_create_element
+       (_gnutls_get_gnutls_asn (), "GNUTLS.ECParameters", &spk)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (ret);
+    }
+
+  ret = asn1_der_decoding (&spk, der, dersize, NULL);
+
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      ret = _gnutls_asn2err (ret);
+      goto cleanup;
+    }
+
+  /* Read curve */
+  /* read the curve */
+  oid_size = sizeof(oid);
+  ret = asn1_read_value(spk, "namedCurve", oid, &oid_size);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      ret = _gnutls_asn2err (ret);
+      goto cleanup;
+    }
+    
+  params->flags = _gnutls_oid_to_ecc_curve(oid);
+  if (params->flags == GNUTLS_ECC_CURVE_INVALID)
+    {
+      _gnutls_debug_log("Curve %s is not supported\n", oid);
+      gnutls_assert();
+      ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
+      goto cleanup;
+    }
+    
+  ret = _gnutls_ecc_curve_fill_params(params->flags, params);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+
+  ret = 0;
+  
+cleanup:
+
+  asn1_delete_structure (&spk);
+
+  return ret;
+
+}
+
+int _gnutls_x509_read_pubkey (gnutls_pk_algorithm_t algo, opaque * der, int dersize,
+                                  gnutls_pk_params_st * params)
+{
+  switch(algo)
+    {
+      case GNUTLS_PK_RSA:
+        return _gnutls_x509_read_rsa_pubkey(der, dersize, params);
+      case GNUTLS_PK_DSA:
+        return _gnutls_x509_read_dsa_pubkey(der, dersize, params);
+      case GNUTLS_PK_ECC:
+        return _gnutls_x509_read_ecc_pubkey(der, dersize, params);
+      default:
+        return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
+    }
+}
+
+int _gnutls_x509_read_pubkey_params (gnutls_pk_algorithm_t algo, opaque * der, int dersize,
+                                  gnutls_pk_params_st * params)
+{
+  switch(algo)
+    {
+      case GNUTLS_PK_RSA:
+        return 0;
+      case GNUTLS_PK_DSA:
+        return _gnutls_x509_read_dsa_params(der, dersize, params);
+      case GNUTLS_PK_ECC:
+        return _gnutls_x509_read_ecc_params(der, dersize, params);
+      default:
+        return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
+    }
+}
+
+/* reads DSA's Y
+ * from the certificate 
+ * only sets params[3]
+ */
+int
+_gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, gnutls_pk_params_st * params)
+{
+  /* do not set a number */
+  params->params_nr = 0;
+  return _gnutls_x509_read_der_int (der, dersize, &params->params[3]);
+}
+
diff --git a/lib/x509/key_encode.c b/lib/x509/key_encode.c
new file mode 100644 (file)
index 0000000..8b44d08
--- /dev/null
@@ -0,0 +1,834 @@
+/*
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
+ *
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_errors.h>
+#include <gnutls_global.h>
+#include <libtasn1.h>
+#include <gnutls_datum.h>
+#include "common.h"
+#include "x509_int.h"
+#include <gnutls_num.h>
+#include <gnutls_pk.h>
+#include <gnutls_mpi.h>
+#include <gnutls_ecc.h>
+
+static int _gnutls_x509_write_rsa_pubkey (gnutls_pk_params_st * params, 
+                                   gnutls_datum_t * der);
+static int _gnutls_x509_write_dsa_params (gnutls_pk_params_st * params,
+                                   gnutls_datum_t * der);
+static int _gnutls_x509_write_dsa_pubkey (gnutls_pk_params_st * params,
+                                       gnutls_datum_t * der);
+
+static int _gnutls_x509_write_ecc_params (gnutls_pk_params_st * params,
+                                   gnutls_datum_t * der);
+static int _gnutls_x509_write_ecc_pubkey (gnutls_pk_params_st * params,
+                                       gnutls_datum_t * der);
+
+
+/*
+ * some x509 certificate functions that relate to MPI parameter
+ * setting. This writes the BIT STRING subjectPublicKey.
+ * Needs 2 parameters (m,e).
+ *
+ * Allocates the space used to store the DER data.
+ */
+static int
+_gnutls_x509_write_rsa_pubkey (gnutls_pk_params_st * params,
+                               gnutls_datum_t * der)
+{
+  int result;
+  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+
+  der->data = NULL;
+  der->size = 0;
+
+  if (params->params_nr < RSA_PUBLIC_PARAMS)
+    {
+      gnutls_assert ();
+      result = GNUTLS_E_INVALID_REQUEST;
+      goto cleanup;
+    }
+
+  if ((result = asn1_create_element
+       (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk))
+      != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = _gnutls_x509_write_int (spk, "modulus", params->params[0], 1);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_x509_write_int (spk, "publicExponent", params->params[1], 1);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_x509_der_encode (spk, "", der, 0);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = 0;
+
+cleanup:
+  asn1_delete_structure (&spk);
+
+  return result;
+}
+
+/*
+ * some x509 certificate functions that relate to MPI parameter
+ * setting. This writes an ECPoint.
+ *
+ * Allocates the space used to store the DER data.
+ */
+static int
+_gnutls_x509_write_ecc_pubkey (gnutls_pk_params_st * params,
+                               gnutls_datum_t * der)
+{
+  int result;
+  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+  gnutls_datum_t out;
+
+  der->data = NULL;
+  der->size = 0;
+
+  if (params->params_nr < ECC_PUBLIC_PARAMS)
+    {
+      gnutls_assert ();
+      result = GNUTLS_E_INVALID_REQUEST;
+      goto cleanup;
+    }
+
+  result = _gnutls_ecc_ansi_x963_export(params->flags, params->params[5], params->params[6], &out);
+  if (result < 0)
+    return gnutls_assert_val(result);
+
+  if ((result = asn1_create_element
+       (_gnutls_get_gnutls_asn (), "GNUTLS.ECPoint", &spk))
+      != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  result = asn1_write_value (spk, "", out.data, out.size);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+  
+  result = _gnutls_x509_der_encode (spk, "", der, 0);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = 0;
+
+cleanup:
+  _gnutls_free_datum(&out);
+  asn1_delete_structure (&spk);
+
+  return result;
+}
+
+int
+_gnutls_x509_write_pubkey_params (gnutls_pk_algorithm_t algo,
+                                   gnutls_pk_params_st* params,
+                                   gnutls_datum_t * der)
+{
+  switch(algo)
+    {
+      case GNUTLS_PK_DSA:
+        return _gnutls_x509_write_dsa_params(params, der);
+      case GNUTLS_PK_RSA:
+        der->data = gnutls_malloc(ASN1_NULL_SIZE);
+        if (der->data == NULL)
+          return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+        
+        memcpy(der->data, ASN1_NULL, ASN1_NULL_SIZE);
+        der->size = ASN1_NULL_SIZE;
+        return 0;
+      case GNUTLS_PK_ECC:
+        return _gnutls_x509_write_ecc_params(params, der);
+      default:
+        return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
+    }
+}
+
+int
+_gnutls_x509_write_pubkey (gnutls_pk_algorithm_t algo,
+                                   gnutls_pk_params_st* params,
+                                   gnutls_datum_t * der)
+{
+  switch(algo)
+    {
+      case GNUTLS_PK_DSA:
+        return _gnutls_x509_write_dsa_pubkey(params, der);
+      case GNUTLS_PK_RSA:
+        return _gnutls_x509_write_rsa_pubkey(params, der);
+      case GNUTLS_PK_ECC:
+        return _gnutls_x509_write_ecc_pubkey(params, der);
+      default:
+        return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
+    }
+}
+
+/*
+ * This function writes the parameters for DSS keys.
+ * Needs 3 parameters (p,q,g).
+ *
+ * Allocates the space used to store the DER data.
+ */
+static int
+_gnutls_x509_write_dsa_params (gnutls_pk_params_st* params,
+                               gnutls_datum_t * der)
+{
+  int result;
+  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+
+  der->data = NULL;
+  der->size = 0;
+
+  if (params->params_nr < DSA_PUBLIC_PARAMS-1)
+    {
+      gnutls_assert ();
+      result = GNUTLS_E_INVALID_REQUEST;
+      goto cleanup;
+    }
+
+  if ((result = asn1_create_element
+       (_gnutls_get_gnutls_asn (), "GNUTLS.DSAParameters", &spk))
+      != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = _gnutls_x509_write_int (spk, "p", params->params[0], 1);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_x509_write_int (spk, "q", params->params[1], 1);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_x509_write_int (spk, "g", params->params[2], 1);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_x509_der_encode (spk, "", der, 0);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = 0;
+
+cleanup:
+  asn1_delete_structure (&spk);
+  return result;
+}
+
+/*
+ * This function writes the parameters for ECC keys.
+ * That is the ECParameters struct.
+ *
+ * Allocates the space used to store the DER data.
+ */
+static int
+_gnutls_x509_write_ecc_params (gnutls_pk_params_st* params,
+                               gnutls_datum_t * der)
+{
+  int result;
+  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+  const char* oid;
+
+  der->data = NULL;
+  der->size = 0;
+
+  if (params->params_nr < ECC_PUBLIC_PARAMS)
+    {
+      gnutls_assert ();
+      result = GNUTLS_E_INVALID_REQUEST;
+      goto cleanup;
+    }
+
+  oid = _gnutls_ecc_curve_get_oid(params->flags);
+  if (oid == NULL)
+    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+
+  if ((result = asn1_create_element
+       (_gnutls_get_gnutls_asn (), "GNUTLS.ECParameters", &spk))
+      != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  if ((result = asn1_write_value (spk, "parameters", "namedCurve", 1)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+  
+  if ((result = asn1_write_value (spk, "parameters.namedCurve", oid, 1)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  result = _gnutls_x509_der_encode (spk, "", der, 0);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = 0;
+
+cleanup:
+  asn1_delete_structure (&spk);
+  return result;
+}
+
+/*
+ * This function writes the public parameters for DSS keys.
+ * Needs 1 parameter (y).
+ *
+ * Allocates the space used to store the DER data.
+ */
+static int
+_gnutls_x509_write_dsa_pubkey (gnutls_pk_params_st * params,
+                                   gnutls_datum_t * der)
+{
+  int result;
+  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+
+  der->data = NULL;
+  der->size = 0;
+
+  if (params->params_nr < DSA_PUBLIC_PARAMS)
+    {
+      gnutls_assert ();
+      result = GNUTLS_E_INVALID_REQUEST;
+      goto cleanup;
+    }
+
+  if ((result = asn1_create_element
+       (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey", &spk))
+      != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = _gnutls_x509_write_int (spk, "", params->params[3], 1);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_x509_der_encode (spk, "", der, 0);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = 0;
+
+cleanup:
+  asn1_delete_structure (&spk);
+  return result;
+}
+
+/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
+ */
+static int
+_gnutls_asn1_encode_rsa (ASN1_TYPE * c2, gnutls_pk_params_st * params)
+{
+  int result;
+  opaque null = '\0';
+  gnutls_pk_params_st pk_params;
+  gnutls_datum_t m, e, d, p, q, u, exp1, exp2;
+
+  gnutls_pk_params_init(&pk_params);
+
+  memset (&m, 0, sizeof (m));
+  memset (&p, 0, sizeof (p));
+  memset (&q, 0, sizeof (q));
+  memset (&p, 0, sizeof (p));
+  memset (&u, 0, sizeof (u));
+  memset (&e, 0, sizeof (e));
+  memset (&d, 0, sizeof (d));
+  memset (&exp1, 0, sizeof (exp1));
+  memset (&exp2, 0, sizeof (exp2));
+
+  result = _gnutls_pk_params_copy (&pk_params, params);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  /* retrieve as data */
+
+  result = _gnutls_mpi_dprint_lz (pk_params.params[0], &m);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_mpi_dprint_lz (pk_params.params[1], &e);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_mpi_dprint_lz (pk_params.params[2], &d);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_mpi_dprint_lz (pk_params.params[3], &p);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_mpi_dprint_lz (pk_params.params[4], &q);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_mpi_dprint_lz (pk_params.params[5], &u);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_mpi_dprint_lz (pk_params.params[6], &exp1);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = _gnutls_mpi_dprint_lz (pk_params.params[7], &exp2);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  /* Ok. Now we have the data. Create the asn1 structures
+   */
+
+  /* first make sure that no previously allocated data are leaked */
+  if (*c2 != ASN1_TYPE_EMPTY)
+    {
+      asn1_delete_structure (c2);
+      *c2 = ASN1_TYPE_EMPTY;
+    }
+
+  if ((result = asn1_create_element
+       (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey", c2))
+      != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  /* Write PRIME 
+   */
+  if ((result = asn1_write_value (*c2, "modulus",
+                                  m.data, m.size)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "publicExponent",
+                                  e.data, e.size)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "privateExponent",
+                                  d.data, d.size)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "prime1",
+                                  p.data, p.size)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "prime2",
+                                  q.data, q.size)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "coefficient",
+                                  u.data, u.size)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "exponent1",
+                                  exp1.data, exp1.size)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "exponent2",
+                                  exp2.data, exp2.size)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "otherPrimeInfos",
+                                  NULL, 0)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  result = 0;
+
+cleanup:
+  if (result != 0)
+    asn1_delete_structure (c2);
+
+  gnutls_pk_params_release (&pk_params);
+
+  _gnutls_free_datum (&m);
+  _gnutls_free_datum (&d);
+  _gnutls_free_datum (&e);
+  _gnutls_free_datum (&p);
+  _gnutls_free_datum (&q);
+  _gnutls_free_datum (&u);
+  _gnutls_free_datum (&exp1);
+  _gnutls_free_datum (&exp2);
+
+  return result;
+}
+
+/* Encodes the ECC parameters into an ASN.1 ECPrivateKey structure.
+ */
+static int
+_gnutls_asn1_encode_ecc (ASN1_TYPE * c2, gnutls_pk_params_st * params)
+{
+  int ret;
+  opaque one = '\x01';
+  gnutls_datum pubkey = { NULL, 0 };
+  const char *oid;
+  
+  oid = _gnutls_ecc_curve_get_oid(params->flags);
+
+  if (params->params_nr != ECC_PRIVATE_PARAMS || oid == NULL)
+    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+  ret = _gnutls_ecc_ansi_x963_export(params->flags, params->params[5], params->params[6], &pubkey);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+  
+  /* Ok. Now we have the data. Create the asn1 structures
+   */
+
+  /* first make sure that no previously allocated data are leaked */
+  if (*c2 != ASN1_TYPE_EMPTY)
+    {
+      asn1_delete_structure (c2);
+      *c2 = ASN1_TYPE_EMPTY;
+    }
+
+  if ((ret = asn1_create_element
+       (_gnutls_get_gnutls_asn (), "GNUTLS.ECPrivateKey", c2))
+      != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      ret = _gnutls_asn2err (ret);
+      goto cleanup;
+    }
+
+  /* Write PRIME 
+   */
+  if ((ret = asn1_write_value (*c2, "version", &one, 1)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      ret = _gnutls_asn2err (ret);
+      goto cleanup;
+    }
+
+  ret = _gnutls_x509_write_int (*c2, "privateKey", params->params[8], 1);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  if ((ret = asn1_write_value (*c2, "publibKey", pubkey.data, pubkey.size)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      ret = _gnutls_asn2err (ret);
+      goto cleanup;
+    }
+
+  /* write our choice */
+  if ((ret = asn1_write_value (*c2, "parameters", "namedCurve", 1)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      ret = _gnutls_asn2err (ret);
+      goto cleanup;
+    }
+  
+  if ((ret = asn1_write_value (*c2, "parameters.namedCurve", oid, 1)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      ret = _gnutls_asn2err (ret);
+      goto cleanup;
+    }
+
+  _gnutls_free_datum(&pubkey);
+  return 0;
+
+cleanup:
+  asn1_delete_structure (c2);
+  _gnutls_free_datum(&pubkey);
+
+  return ret;
+}
+
+
+/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
+ */
+static int
+_gnutls_asn1_encode_dsa (ASN1_TYPE * c2, gnutls_pk_params_st * params)
+{
+  int result, i;
+  size_t size[DSA_PRIVATE_PARAMS], total;
+  opaque *p_data, *q_data, *g_data, *x_data, *y_data;
+  opaque *all_data = NULL, *p;
+  opaque null = '\0';
+
+  /* Read all the sizes */
+  total = 0;
+  for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
+    {
+      _gnutls_mpi_print_lz (params->params[i], NULL, &size[i]);
+      total += size[i];
+    }
+
+  /* Encoding phase.
+   * allocate data enough to hold everything
+   */
+  all_data = gnutls_secure_malloc (total);
+  if (all_data == NULL)
+    {
+      gnutls_assert ();
+      result = GNUTLS_E_MEMORY_ERROR;
+      goto cleanup;
+    }
+
+  p = all_data;
+  p_data = p;
+  p += size[0];
+  q_data = p;
+  p += size[1];
+  g_data = p;
+  p += size[2];
+  y_data = p;
+  p += size[3];
+  x_data = p;
+
+  _gnutls_mpi_print_lz (params->params[0], p_data, &size[0]);
+  _gnutls_mpi_print_lz (params->params[1], q_data, &size[1]);
+  _gnutls_mpi_print_lz (params->params[2], g_data, &size[2]);
+  _gnutls_mpi_print_lz (params->params[3], y_data, &size[3]);
+  _gnutls_mpi_print_lz (params->params[4], x_data, &size[4]);
+
+  /* Ok. Now we have the data. Create the asn1 structures
+   */
+
+  /* first make sure that no previously allocated data are leaked */
+  if (*c2 != ASN1_TYPE_EMPTY)
+    {
+      asn1_delete_structure (c2);
+      *c2 = ASN1_TYPE_EMPTY;
+    }
+
+  if ((result = asn1_create_element
+       (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPrivateKey", c2))
+      != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  /* Write PRIME 
+   */
+  if ((result = asn1_write_value (*c2, "p", p_data, size[0])) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "q", q_data, size[1])) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "g", g_data, size[2])) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "Y", y_data, size[3])) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  if ((result = asn1_write_value (*c2, "priv",
+                                  x_data, size[4])) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  gnutls_free (all_data);
+
+  if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      result = _gnutls_asn2err (result);
+      goto cleanup;
+    }
+
+  return 0;
+
+cleanup:
+  asn1_delete_structure (c2);
+  gnutls_free (all_data);
+
+  return result;
+}
+
+int _gnutls_asn1_encode_privkey (gnutls_pk_algorithm_t pk, ASN1_TYPE * c2, gnutls_pk_params_st * params)
+{
+  switch(pk)
+    {
+      case GNUTLS_PK_RSA:
+        return _gnutls_asn1_encode_rsa(c2, params);
+      case GNUTLS_PK_DSA:
+        return _gnutls_asn1_encode_dsa(c2, params);
+      case GNUTLS_PK_ECC:
+        return _gnutls_asn1_encode_ecc(c2, params);
+      default:
+        return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+    }
+}
index 1bd26cbb4aad9509881f72b9432f55a3dccafaa6..b57e7988a8c251c38fe5bd67d2b3ff062ff32807 100644 (file)
 #include "common.h"
 #include "x509_int.h"
 #include <gnutls_num.h>
+#include <gnutls_ecc.h>
 
-/*
- * some x509 certificate parsing functions that relate to MPI parameter
- * extraction. This reads the BIT STRING subjectPublicKey.
- * Returns 2 parameters (m,e).
- */
-int
-_gnutls_x509_read_rsa_params (opaque * der, int dersize, bigint_t * params)
-{
-  int result;
-  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
-
-  if ((result = asn1_create_element
-       (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk))
-      != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      return _gnutls_asn2err (result);
-    }
-
-  result = asn1_der_decoding (&spk, der, dersize, NULL);
-
-  if (result != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&spk);
-      return _gnutls_asn2err (result);
-    }
-
-
-  if ((result = _gnutls_x509_read_int (spk, "modulus", &params[0])) < 0)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&spk);
-      return GNUTLS_E_ASN1_GENERIC_ERROR;
-    }
-
-  if ((result = _gnutls_x509_read_int (spk, "publicExponent",
-                                       &params[1])) < 0)
-    {
-      gnutls_assert ();
-      _gnutls_mpi_release (&params[0]);
-      asn1_delete_structure (&spk);
-      return GNUTLS_E_ASN1_GENERIC_ERROR;
-    }
-
-  asn1_delete_structure (&spk);
-
-  return 0;
-
-}
-
-
-/* reads p,q and g 
- * from the certificate (subjectPublicKey BIT STRING).
- * params[0-2]
- */
-int
-_gnutls_x509_read_dsa_params (opaque * der, int dersize, bigint_t * params)
-{
-  int result;
-  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
-
-  if ((result = asn1_create_element
-       (_gnutls_get_pkix (), "PKIX1.Dss-Parms", &spk)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      return _gnutls_asn2err (result);
-    }
-
-  result = asn1_der_decoding (&spk, der, dersize, NULL);
-
-  if (result != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&spk);
-      return _gnutls_asn2err (result);
-    }
-
-  /* FIXME: If the parameters are not included in the certificate
-   * then the issuer's parameters should be used. This is not
-   * done yet.
-   */
-
-  /* Read p */
-
-  if ((result = _gnutls_x509_read_int (spk, "p", &params[0])) < 0)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&spk);
-      return GNUTLS_E_ASN1_GENERIC_ERROR;
-    }
-
-  /* Read q */
-
-  if ((result = _gnutls_x509_read_int (spk, "q", &params[1])) < 0)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&spk);
-      _gnutls_mpi_release (&params[0]);
-      return GNUTLS_E_ASN1_GENERIC_ERROR;
-    }
-
-  /* Read g */
-
-  if ((result = _gnutls_x509_read_int (spk, "g", &params[2])) < 0)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&spk);
-      _gnutls_mpi_release (&params[0]);
-      _gnutls_mpi_release (&params[1]);
-      return GNUTLS_E_ASN1_GENERIC_ERROR;
-    }
-
-  asn1_delete_structure (&spk);
-
-  return 0;
-
-}
 
 /* Reads an Integer from the DER encoded data
  */
@@ -193,28 +76,20 @@ _gnutls_x509_read_der_int (opaque * der, int dersize, bigint_t * out)
 
 }
 
-/* reads DSA's Y
- * from the certificate 
- * only sets params[3]
- */
-int
-_gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, bigint_t * params)
-{
-  return _gnutls_x509_read_der_int (der, dersize, &params[3]);
-}
-
 
 /* Extracts DSA and RSA parameters from a certificate.
  */
 int
 _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root,
-                      bigint_t * params, int *params_size)
+                      gnutls_pk_params_st * params)
 {
   int result;
   char name[256];
   gnutls_datum_t tmp = { NULL, 0 };
   gnutls_pk_algorithm_t pk_algorithm;
 
+  gnutls_pk_params_init(params);
+
   result = _gnutls_x509_get_pk_algorithm (asn, root, NULL);
   if (result < 0)
     {
@@ -235,86 +110,36 @@ _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root,
       return result;
     }
 
-  switch (pk_algorithm)
+  if ((result =
+       _gnutls_x509_read_pubkey (pk_algorithm, tmp.data, tmp.size, params)) < 0)
     {
-    case GNUTLS_PK_RSA:
-      /* params[0] is the modulus,
-       * params[1] is the exponent
-       */
-      if (*params_size < RSA_PUBLIC_PARAMS)
-        {
-          gnutls_assert ();
-          /* internal error. Increase the bigint_ts in params */
-          result = GNUTLS_E_INTERNAL_ERROR;
-          goto error;
-        }
-
-      if ((result =
-           _gnutls_x509_read_rsa_params (tmp.data, tmp.size, params)) < 0)
-        {
-          gnutls_assert ();
-          goto error;
-        }
-      *params_size = RSA_PUBLIC_PARAMS;
-
-      break;
-    case GNUTLS_PK_DSA:
-      /* params[0] is p,
-       * params[1] is q,
-       * params[2] is q,
-       * params[3] is pub.
-       */
+      gnutls_assert ();
+      goto error;
+    }
 
-      if (*params_size < DSA_PUBLIC_PARAMS)
-        {
-          gnutls_assert ();
-          /* internal error. Increase the bigint_ts in params */
-          result = GNUTLS_E_INTERNAL_ERROR;
-          goto error;
-        }
-
-      if ((result =
-           _gnutls_x509_read_dsa_pubkey (tmp.data, tmp.size, params)) < 0)
-        {
-          gnutls_assert ();
-          goto error;
-        }
-
-      /* Now read the parameters
-       */
-      _gnutls_free_datum (&tmp);
+  /* Now read the parameters
+   */
+  _gnutls_free_datum (&tmp);
+  _asnstr_append_name (name, sizeof (name), root,
+                       ".algorithm.parameters");
+  result = _gnutls_x509_read_value (asn, name, &tmp, 0);
 
-      _asnstr_append_name (name, sizeof (name), root,
-                           ".algorithm.parameters");
-      result = _gnutls_x509_read_value (asn, name, &tmp, 0);
+  /* FIXME: If the parameters are not included in the certificate
+   * then the issuer's parameters should be used. This is not
+   * done yet.
+   */
 
-      /* FIXME: If the parameters are not included in the certificate
-       * then the issuer's parameters should be used. This is not
-       * done yet.
-       */
+  if (result < 0 && pk_algorithm != GNUTLS_PK_RSA) /* RSA doesn't use parameters */
+    {
+      gnutls_assert ();
+      goto error;
+    }
 
-      if (result < 0)
-        {
-          gnutls_assert ();
-          goto error;
-        }
-
-      if ((result =
-           _gnutls_x509_read_dsa_params (tmp.data, tmp.size, params)) < 0)
-        {
-          gnutls_assert ();
-          goto error;
-        }
-      *params_size = DSA_PUBLIC_PARAMS;
-
-      break;
-
-    default:
-      /* other types like DH
-       * currently not supported
-       */
+  if ((result =
+       _gnutls_x509_read_pubkey_params (pk_algorithm, tmp.data, tmp.size, params)) < 0)
+    {
       gnutls_assert ();
-      result = GNUTLS_E_X509_CERTIFICATE_ERROR;
       goto error;
     }
 
@@ -329,13 +154,12 @@ error:
  */
 int
 _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
-                           bigint_t * params, int *params_size)
+                           gnutls_pk_params_st * params)
 {
   /* Read the algorithm's OID
    */
   return _gnutls_get_asn_mpis (cert->cert,
-                               "tbsCertificate.subjectPublicKeyInfo", params,
-                               params_size);
+                               "tbsCertificate.subjectPublicKeyInfo", params);
 }
 
 #ifdef ENABLE_PKI
@@ -344,78 +168,17 @@ _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
  */
 int
 _gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert,
-                           bigint_t * params, int *params_size)
+                           gnutls_pk_params_st* params)
 {
   /* Read the algorithm's OID
    */
   return _gnutls_get_asn_mpis (cert->crq,
                                "certificationRequestInfo.subjectPKInfo",
-                               params, params_size);
+                               params);
 }
 
 #endif
 
-/*
- * some x509 certificate functions that relate to MPI parameter
- * setting. This writes the BIT STRING subjectPublicKey.
- * Needs 2 parameters (m,e).
- *
- * Allocates the space used to store the DER data.
- */
-int
-_gnutls_x509_write_rsa_params (bigint_t * params, int params_size,
-                               gnutls_datum_t * der)
-{
-  int result;
-  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
-
-  der->data = NULL;
-  der->size = 0;
-
-  if (params_size < 2)
-    {
-      gnutls_assert ();
-      result = GNUTLS_E_INVALID_REQUEST;
-      goto cleanup;
-    }
-
-  if ((result = asn1_create_element
-       (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk))
-      != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      return _gnutls_asn2err (result);
-    }
-
-  result = _gnutls_x509_write_int (spk, "modulus", params[0], 1);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_x509_write_int (spk, "publicExponent", params[1], 1);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_x509_der_encode (spk, "", der, 0);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  asn1_delete_structure (&spk);
-  return 0;
-
-cleanup:
-  asn1_delete_structure (&spk);
-
-  return result;
-}
 
 /*
  * This function writes and encodes the parameters for DSS or RSA keys.
@@ -473,123 +236,7 @@ _gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name,
   return 0;
 }
 
-/*
- * This function writes the parameters for DSS keys.
- * Needs 3 parameters (p,q,g).
- *
- * Allocates the space used to store the DER data.
- */
-int
-_gnutls_x509_write_dsa_params (bigint_t * params, int params_size,
-                               gnutls_datum_t * der)
-{
-  int result;
-  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
-
-  der->data = NULL;
-  der->size = 0;
-
-  if (params_size < 3)
-    {
-      gnutls_assert ();
-      result = GNUTLS_E_INVALID_REQUEST;
-      goto cleanup;
-    }
-
-  if ((result = asn1_create_element
-       (_gnutls_get_gnutls_asn (), "GNUTLS.DSAParameters", &spk))
-      != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      return _gnutls_asn2err (result);
-    }
-
-  result = _gnutls_x509_write_int (spk, "p", params[0], 1);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_x509_write_int (spk, "q", params[1], 1);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_x509_write_int (spk, "g", params[2], 1);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_x509_der_encode (spk, "", der, 0);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = 0;
-
-cleanup:
-  asn1_delete_structure (&spk);
-  return result;
-}
-
-/*
- * This function writes the public parameters for DSS keys.
- * Needs 1 parameter (y).
- *
- * Allocates the space used to store the DER data.
- */
-int
-_gnutls_x509_write_dsa_public_key (bigint_t * params, int params_size,
-                                   gnutls_datum_t * der)
-{
-  int result;
-  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
-
-  der->data = NULL;
-  der->size = 0;
-
-  if (params_size < 3)
-    {
-      gnutls_assert ();
-      result = GNUTLS_E_INVALID_REQUEST;
-      goto cleanup;
-    }
 
-  if ((result = asn1_create_element
-       (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey", &spk))
-      != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      return _gnutls_asn2err (result);
-    }
-
-  result = _gnutls_x509_write_int (spk, "", params[3], 1);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_x509_der_encode (spk, "", der, 0);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = 0;
-
-cleanup:
-  asn1_delete_structure (&spk);
-  return result;
-}
 
 
 /* this function reads a (small) unsigned integer
index 66f3290489085b8e096504a3a544d998368890b4..925a97032e055def32a0c18648feb14231533251 100644 (file)
@@ -35,8 +35,7 @@
 #include <x509_int.h>
 #include <gnutls_pk.h>
 #include <gnutls_mpi.h>
-
-static int _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, bigint_t * params);
+#include <gnutls_ecc.h>
 
 /**
  * gnutls_x509_privkey_init:
@@ -71,16 +70,10 @@ gnutls_x509_privkey_init (gnutls_x509_privkey_t * key)
 void
 gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key)
 {
-  int i;
-
   if (!key)
     return;
 
-  for (i = 0; i < key->params_size; i++)
-    {
-      _gnutls_mpi_release (&key->params[i]);
-    }
-
+  gnutls_pk_params_release(&key->params);
   asn1_delete_structure (&key->key);
   gnutls_free (key);
 }
@@ -104,40 +97,26 @@ gnutls_x509_privkey_cpy (gnutls_x509_privkey_t dst, gnutls_x509_privkey_t src)
   if (!src || !dst)
     return GNUTLS_E_INVALID_REQUEST;
 
-  for (i = 0; i < src->params_size; i++)
+  for (i = 0; i < src->params.params_nr; i++)
     {
-      dst->params[i] = _gnutls_mpi_copy (src->params[i]);
-      if (dst->params[i] == NULL)
+      dst->params.params[i] = _gnutls_mpi_copy (src->params.params[i]);
+      if (dst->params.params[i] == NULL)
         return GNUTLS_E_MEMORY_ERROR;
     }
 
-  dst->params_size = src->params_size;
+  dst->params.params_nr = src->params.params_nr;
+  dst->params.flags = src->params.flags;
+
   dst->pk_algorithm = src->pk_algorithm;
   dst->crippled = src->crippled;
 
   if (!src->crippled)
     {
-      switch (dst->pk_algorithm)
+      ret = _gnutls_asn1_encode_privkey (dst->pk_algorithm, &dst->key, &dst->params);
+      if (ret < 0)
         {
-        case GNUTLS_PK_DSA:
-          ret = _gnutls_asn1_encode_dsa (&dst->key, dst->params);
-          if (ret < 0)
-            {
-              gnutls_assert ();
-              return ret;
-            }
-          break;
-        case GNUTLS_PK_RSA:
-          ret = _gnutls_asn1_encode_rsa (&dst->key, dst->params);
-          if (ret < 0)
-            {
-              gnutls_assert ();
-              return ret;
-            }
-          break;
-        default:
           gnutls_assert ();
-          return GNUTLS_E_INVALID_REQUEST;
+          return ret;
         }
     }
 
@@ -153,10 +132,9 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key,
 {
   int result;
   ASN1_TYPE pkey_asn;
-  gnutls_pk_params_st pk_params;
 
-  memset (&pk_params, 0, sizeof (pk_params));
-  pk_params.params_nr = RSA_PRIVATE_PARAMS;
+  gnutls_pk_params_init(&pkey->params);
+
 
   if ((result =
        asn1_create_element (_gnutls_get_gnutls_asn (),
@@ -175,7 +153,7 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key,
     }
 
   if ((result = _gnutls_x509_read_int (pkey_asn, "modulus",
-                                       &pk_params.params[0])) < 0)
+                                       &pkey->params.params[0])) < 0)
     {
       gnutls_assert ();
       goto error;
@@ -183,7 +161,7 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key,
 
   if ((result =
        _gnutls_x509_read_int (pkey_asn, "publicExponent",
-                              &pk_params.params[1])) < 0)
+                              &pkey->params.params[1])) < 0)
     {
       gnutls_assert ();
       goto error;
@@ -191,74 +169,174 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key,
 
   if ((result =
        _gnutls_x509_read_int (pkey_asn, "privateExponent",
-                              &pk_params.params[2])) < 0)
+                              &pkey->params.params[2])) < 0)
     {
       gnutls_assert ();
       goto error;
     }
 
   if ((result = _gnutls_x509_read_int (pkey_asn, "prime1",
-                                       &pk_params.params[3])) < 0)
+                                       &pkey->params.params[3])) < 0)
     {
       gnutls_assert ();
       goto error;
     }
 
   if ((result = _gnutls_x509_read_int (pkey_asn, "prime2",
-                                       &pk_params.params[4])) < 0)
+                                       &pkey->params.params[4])) < 0)
     {
       gnutls_assert ();
       goto error;
     }
 
   if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient",
-                                       &pk_params.params[5])) < 0)
+                                       &pkey->params.params[5])) < 0)
     {
       gnutls_assert ();
       goto error;
     }
 
   if ((result = _gnutls_x509_read_int (pkey_asn, "exponent1",
-                                       &pk_params.params[6])) < 0)
+                                       &pkey->params.params[6])) < 0)
     {
       gnutls_assert ();
       goto error;
     }
 
   if ((result = _gnutls_x509_read_int (pkey_asn, "exponent2",
-                                       &pk_params.params[7])) < 0)
+                                       &pkey->params.params[7])) < 0)
     {
       gnutls_assert ();
       goto error;
     }
 
 
-  result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pk_params);
+  result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pkey->params);
   if (result < 0)
     {
       gnutls_assert ();
       goto error;
     }
 
-  pkey->params[0] = pk_params.params[0];
-  pkey->params[1] = pk_params.params[1];
-  pkey->params[2] = pk_params.params[2];
-  pkey->params[3] = pk_params.params[3];
-  pkey->params[4] = pk_params.params[4];
-  pkey->params[5] = pk_params.params[5];
-  pkey->params[6] = pk_params.params[6];
-  pkey->params[7] = pk_params.params[7];
-  pkey->params_size = pk_params.params_nr;
+  pkey->params.params_nr = RSA_PRIVATE_PARAMS;
 
   return pkey_asn;
 
 error:
   asn1_delete_structure (&pkey_asn);
-  gnutls_pk_params_release (&pk_params);
+  gnutls_pk_params_release (&pkey->params);
+  return NULL;
+
+}
+
+/* Converts an ECC key to
+ * an internal structure (gnutls_private_key)
+ */
+ASN1_TYPE
+_gnutls_privkey_decode_ecc_key (const gnutls_datum_t * raw_key,
+                                      gnutls_x509_privkey_t pkey)
+{
+  int ret;
+  ASN1_TYPE pkey_asn;
+  unsigned int version;
+  char oid[MAX_OID_SIZE];
+  unsigned int oid_size;
+  gnutls_datum out;
+
+  gnutls_pk_params_init(&pkey->params);
+
+  if ((ret =
+       asn1_create_element (_gnutls_get_gnutls_asn (),
+                            "GNUTLS.ECPrivateKey",
+                            &pkey_asn)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return NULL;
+    }
+
+  ret = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      goto error;
+    }
+
+  ret = _gnutls_x509_read_uint (pkey_asn, "Version", &version);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto error;
+    }
+
+  if (version != 1)
+    {
+      _gnutls_debug_log("ECC private key version %u is not supported\n", version);
+      gnutls_assert();
+      goto error;
+    }
+
+  /* read the curve */
+  oid_size = sizeof(oid);
+  ret = asn1_read_value(pkey_asn, "parameters.namedCurve", oid, &oid_size);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      goto error;
+    }
+    
+  pkey->params.flags = _gnutls_oid_to_ecc_curve(oid);
+  if (pkey->params.flags == GNUTLS_ECC_CURVE_INVALID)
+    {
+      _gnutls_debug_log("Curve %s is not supported\n", oid);
+      gnutls_assert();
+      goto error;
+    }
+    
+  ret = _gnutls_ecc_curve_fill_params(pkey->params.flags, &pkey->params);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto error;
+    }
+
+  /* read the public key */
+  ret = _gnutls_x509_read_value(pkey_asn, "publicKey", &out, 2);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto error;
+    }
+
+  ret = _gnutls_ecc_ansi_x963_import (out.data, out.size, &pkey->params.params[5],
+                                         &pkey->params.params[6]);
+  
+  _gnutls_free_datum(&out);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto error;
+    }
+  pkey->params.params_nr += 2;
+
+  /* read the private key */
+  ret = _gnutls_x509_read_int (pkey_asn, "privateKey", &pkey->params.params[7]);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto error;
+    }
+  pkey->params.params_nr ++;
+
+  return pkey_asn;
+
+error:
+  asn1_delete_structure (&pkey_asn);
+  gnutls_pk_params_release (&pkey->params);
   return NULL;
 
 }
 
+
 static ASN1_TYPE
 decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey)
 {
@@ -274,54 +352,57 @@ decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey)
       return NULL;
     }
 
+  pkey->params.params_nr = 0;
+
   result = asn1_der_decoding (&dsa_asn, raw_key->data, raw_key->size, NULL);
   if (result != ASN1_SUCCESS)
     {
       gnutls_assert ();
       goto error;
     }
+  pkey->params.params_nr++;
 
-  if ((result = _gnutls_x509_read_int (dsa_asn, "p", &pkey->params[0])) < 0)
+  if ((result = _gnutls_x509_read_int (dsa_asn, "p", &pkey->params.params[0])) < 0)
     {
       gnutls_assert ();
       goto error;
     }
+  pkey->params.params_nr++;
 
-  if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params[1])) < 0)
+  if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params.params[1])) < 0)
     {
       gnutls_assert ();
       goto error;
     }
+  pkey->params.params_nr++;
 
-  if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params[2])) < 0)
+  if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params.params[2])) < 0)
     {
       gnutls_assert ();
       goto error;
     }
+  pkey->params.params_nr++;
 
-  if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params[3])) < 0)
+  if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params.params[3])) < 0)
     {
       gnutls_assert ();
       goto error;
     }
+  pkey->params.params_nr++;
 
   if ((result = _gnutls_x509_read_int (dsa_asn, "priv",
-                                       &pkey->params[4])) < 0)
+                                       &pkey->params.params[4])) < 0)
     {
       gnutls_assert ();
       goto error;
     }
-  pkey->params_size = 5;
+  pkey->params.params_nr++;
 
   return dsa_asn;
 
 error:
   asn1_delete_structure (&dsa_asn);
-  _gnutls_mpi_release (&pkey->params[0]);
-  _gnutls_mpi_release (&pkey->params[1]);
-  _gnutls_mpi_release (&pkey->params[2]);
-  _gnutls_mpi_release (&pkey->params[3]);
-  _gnutls_mpi_release (&pkey->params[4]);
+  gnutls_pk_params_release(&pkey->params);
   return NULL;
 
 }
@@ -414,6 +495,12 @@ gnutls_x509_privkey_import (gnutls_x509_privkey_t key,
       if (key->key == NULL)
         gnutls_assert ();
     }
+  else if (key->pk_algorithm == GNUTLS_PK_ECC)
+    {
+      key->key = _gnutls_privkey_decode_ecc_key (&_data, key);
+      if (key->key == NULL)
+        gnutls_assert ();
+    }
   else
     {
       /* Try decoding with both, and accept the one that
@@ -463,11 +550,6 @@ failover:
   return result;
 }
 
-#define FREE_RSA_PRIVATE_PARAMS for (i=0;i<RSA_PRIVATE_PARAMS;i++) \
-               _gnutls_mpi_release(&key->params[i])
-#define FREE_DSA_PRIVATE_PARAMS for (i=0;i<DSA_PRIVATE_PARAMS;i++) \
-               _gnutls_mpi_release(&key->params[i])
-
 /**
  * gnutls_x509_privkey_import_rsa_raw:
  * @key: The structure to store the parsed key
@@ -528,11 +610,10 @@ gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key,
                                      const gnutls_datum_t * e1,
                                      const gnutls_datum_t * e2)
 {
-  int i = 0, ret;
+  int ret;
   size_t siz = 0;
-  gnutls_pk_params_st pk_params;
 
-  memset (&pk_params, 0, sizeof (pk_params));
+  gnutls_pk_params_init(&key->params);
 
   if (key == NULL)
     {
@@ -540,120 +621,109 @@ gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  key->params_size = 0;
+  key->params.params_nr = 0;
 
   siz = m->size;
-  if (_gnutls_mpi_scan_nz (&key->params[0], m->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz))
     {
       gnutls_assert ();
-      FREE_RSA_PRIVATE_PARAMS;
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
-  key->params_size++;
+  key->params.params_nr++;
 
   siz = e->size;
-  if (_gnutls_mpi_scan_nz (&key->params[1], e->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz))
     {
       gnutls_assert ();
-      FREE_RSA_PRIVATE_PARAMS;
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
-  key->params_size++;
+  key->params.params_nr++;
 
   siz = d->size;
-  if (_gnutls_mpi_scan_nz (&key->params[2], d->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[2], d->data, siz))
     {
       gnutls_assert ();
-      FREE_RSA_PRIVATE_PARAMS;
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
-  key->params_size++;
+  key->params.params_nr++;
 
   siz = p->size;
-  if (_gnutls_mpi_scan_nz (&key->params[3], p->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[3], p->data, siz))
     {
       gnutls_assert ();
-      FREE_RSA_PRIVATE_PARAMS;
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
-  key->params_size++;
+  key->params.params_nr++;
 
   siz = q->size;
-  if (_gnutls_mpi_scan_nz (&key->params[4], q->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[4], q->data, siz))
     {
       gnutls_assert ();
-      FREE_RSA_PRIVATE_PARAMS;
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
-  key->params_size++;
+  key->params.params_nr++;
 
   siz = u->size;
-  if (_gnutls_mpi_scan_nz (&key->params[5], u->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[5], u->data, siz))
     {
       gnutls_assert ();
-      FREE_RSA_PRIVATE_PARAMS;
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
-  key->params_size++;
+  key->params.params_nr++;
 
   if (e1 && e2)
     {
       siz = e1->size;
-      if (_gnutls_mpi_scan_nz (&key->params[6], e1->data, siz))
+      if (_gnutls_mpi_scan_nz (&key->params.params[6], e1->data, siz))
         {
           gnutls_assert ();
-          FREE_RSA_PRIVATE_PARAMS;
-          return GNUTLS_E_MPI_SCAN_FAILED;
+          ret = GNUTLS_E_MPI_SCAN_FAILED;
+          goto cleanup;
         }
-      key->params_size++;
+      key->params.params_nr++;
 
       siz = e2->size;
-      if (_gnutls_mpi_scan_nz (&key->params[7], e2->data, siz))
+      if (_gnutls_mpi_scan_nz (&key->params.params[7], e2->data, siz))
         {
           gnutls_assert ();
-          FREE_RSA_PRIVATE_PARAMS;
-          return GNUTLS_E_MPI_SCAN_FAILED;
+          ret = GNUTLS_E_MPI_SCAN_FAILED;
+          goto cleanup;
         }
-      key->params_size++;
-    }
-
-  for (i = 0; i < key->params_size; i++)
-    {
-      pk_params.params[i] = key->params[i];
+      key->params.params_nr++;
     }
 
-  pk_params.params_nr = key->params_size;
-
-  ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pk_params);
+  ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params);
   if (ret < 0)
     {
       gnutls_assert ();
-      FREE_RSA_PRIVATE_PARAMS;
-      return ret;
-    }
-
-  for (i = 0; i < pk_params.params_nr; i++)
-    {
-      key->params[i] = pk_params.params[i];
+      goto cleanup;
     }
-  key->params_size = pk_params.params_nr;
 
   if (!key->crippled)
     {
-      ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
+      ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_RSA, &key->key, &key->params);
       if (ret < 0)
         {
           gnutls_assert ();
-          FREE_RSA_PRIVATE_PARAMS;
-          return ret;
+          goto cleanup;
         }
     }
 
-  key->params_size = RSA_PRIVATE_PARAMS;
+  key->params.params_nr = RSA_PRIVATE_PARAMS;
   key->pk_algorithm = GNUTLS_PK_RSA;
 
   return 0;
 
+cleanup:
+  gnutls_pk_params_release(&key->params);
+  return ret;
+
 }
 
 /**
@@ -680,7 +750,7 @@ gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key,
                                     const gnutls_datum_t * y,
                                     const gnutls_datum_t * x)
 {
-  int i = 0, ret;
+  int ret;
   size_t siz = 0;
 
   if (key == NULL)
@@ -690,61 +760,64 @@ gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key,
     }
 
   siz = p->size;
-  if (_gnutls_mpi_scan_nz (&key->params[0], p->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz))
     {
       gnutls_assert ();
-      FREE_DSA_PRIVATE_PARAMS;
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
 
   siz = q->size;
-  if (_gnutls_mpi_scan_nz (&key->params[1], q->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz))
     {
       gnutls_assert ();
-      FREE_DSA_PRIVATE_PARAMS;
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
 
   siz = g->size;
-  if (_gnutls_mpi_scan_nz (&key->params[2], g->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz))
     {
       gnutls_assert ();
-      FREE_DSA_PRIVATE_PARAMS;
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
 
   siz = y->size;
-  if (_gnutls_mpi_scan_nz (&key->params[3], y->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz))
     {
       gnutls_assert ();
-      FREE_DSA_PRIVATE_PARAMS;
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
 
   siz = x->size;
-  if (_gnutls_mpi_scan_nz (&key->params[4], x->data, siz))
+  if (_gnutls_mpi_scan_nz (&key->params.params[4], x->data, siz))
     {
       gnutls_assert ();
-      FREE_DSA_PRIVATE_PARAMS;
-      return GNUTLS_E_MPI_SCAN_FAILED;
+      ret = GNUTLS_E_MPI_SCAN_FAILED;
+      goto cleanup;
     }
 
   if (!key->crippled)
     {
-      ret = _gnutls_asn1_encode_dsa (&key->key, key->params);
+      ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_DSA, &key->key, &key->params);
       if (ret < 0)
         {
           gnutls_assert ();
-          FREE_DSA_PRIVATE_PARAMS;
-          return ret;
+          goto cleanup;
         }
     }
 
-  key->params_size = DSA_PRIVATE_PARAMS;
+  key->params.params_nr = DSA_PRIVATE_PARAMS;
   key->pk_algorithm = GNUTLS_PK_DSA;
 
   return 0;
 
+cleanup:
+  gnutls_pk_params_release(&key->params);
+  return ret;
+
 }
 
 
@@ -814,29 +887,12 @@ gnutls_x509_privkey_export (gnutls_x509_privkey_t key,
     msg = NULL;
 
   if (key->crippled)
-    {                           /* encode the parameters on the fly.
-                                 */
-      switch (key->pk_algorithm)
+    {                           /* encode the parameters on the fly. */
+      ret = _gnutls_asn1_encode_privkey (key->pk_algorithm, &key->key, &key->params);
+      if (ret < 0)
         {
-        case GNUTLS_PK_DSA:
-          ret = _gnutls_asn1_encode_dsa (&key->key, key->params);
-          if (ret < 0)
-            {
-              gnutls_assert ();
-              return ret;
-            }
-          break;
-        case GNUTLS_PK_RSA:
-          ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
-          if (ret < 0)
-            {
-              gnutls_assert ();
-              return ret;
-            }
-          break;
-        default:
           gnutls_assert ();
-          return GNUTLS_E_INVALID_REQUEST;
+          return ret;
         }
     }
 
@@ -857,23 +913,13 @@ gnutls_x509_privkey_export (gnutls_x509_privkey_t key,
 gnutls_sec_param_t
 gnutls_x509_privkey_sec_param (gnutls_x509_privkey_t key)
 {
-  int ret;
+  int bits;
 
-  switch (key->pk_algorithm)
-    {
-    case GNUTLS_PK_RSA:
-      ret = gnutls_pk_bits_to_sec_param (GNUTLS_PK_RSA, _gnutls_mpi_get_nbits (key->params[0]   /*m */
-                                         ));
-      break;
-    case GNUTLS_PK_DSA:
-      ret = gnutls_pk_bits_to_sec_param (GNUTLS_PK_DSA, _gnutls_mpi_get_nbits (key->params[0]   /*p */
-                                         ));
-      break;
-    default:
-      ret = GNUTLS_SEC_PARAM_UNKNOWN;
-    }
-
-  return ret;
+  bits = pubkey_to_bits(key->pk_algorithm, &key->params);
+  if (bits <= 0)
+    return GNUTLS_SEC_PARAM_UNKNOWN;
+  
+  return gnutls_pk_bits_to_sec_param(key->pk_algorithm, bits);
 }
 
 /**
@@ -932,8 +978,8 @@ gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key,
 {
   int ret;
   gnutls_pk_params_st pk_params;
-
-  memset (&pk_params, 0, sizeof (pk_params));
+  
+  gnutls_pk_params_init(&pk_params);
 
   if (key == NULL)
     {
@@ -944,7 +990,7 @@ gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key,
   m->data = e->data = d->data = p->data = q->data = u->data = NULL;
   m->size = e->size = d->size = p->size = q->size = u->size = 0;
 
-  ret = _gnutls_pk_params_copy (&pk_params, key->params, RSA_PRIVATE_PARAMS);
+  ret = _gnutls_pk_params_copy (&pk_params, &key->params);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -998,7 +1044,7 @@ gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key,
     }
 
   /* U */
-  ret = _gnutls_mpi_dprint_lz (key->params[5], u);
+  ret = _gnutls_mpi_dprint_lz (key->params.params[5], u);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1008,7 +1054,7 @@ gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key,
   /* E1 */
   if (e1)
     {
-      ret = _gnutls_mpi_dprint_lz (key->params[6], e1);
+      ret = _gnutls_mpi_dprint_lz (key->params.params[6], e1);
       if (ret < 0)
         {
           gnutls_assert ();
@@ -1019,7 +1065,7 @@ gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key,
   /* E2 */
   if (e2)
     {
-      ret = _gnutls_mpi_dprint_lz (key->params[7], e2);
+      ret = _gnutls_mpi_dprint_lz (key->params.params[7], e2);
       if (ret < 0)
         {
           gnutls_assert ();
@@ -1073,7 +1119,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key,
     }
 
   /* P */
-  ret = _gnutls_mpi_dprint_lz (key->params[0], p);
+  ret = _gnutls_mpi_dprint_lz (key->params.params[0], p);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1081,7 +1127,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key,
     }
 
   /* Q */
-  ret = _gnutls_mpi_dprint_lz (key->params[1], q);
+  ret = _gnutls_mpi_dprint_lz (key->params.params[1], q);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1091,7 +1137,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key,
 
 
   /* G */
-  ret = _gnutls_mpi_dprint_lz (key->params[2], g);
+  ret = _gnutls_mpi_dprint_lz (key->params.params[2], g);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1102,7 +1148,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key,
 
 
   /* Y */
-  ret = _gnutls_mpi_dprint_lz (key->params[3], y);
+  ret = _gnutls_mpi_dprint_lz (key->params.params[3], y);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1113,7 +1159,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key,
     }
 
   /* X */
-  ret = _gnutls_mpi_dprint_lz (key->params[4], x);
+  ret = _gnutls_mpi_dprint_lz (key->params.params[4], x);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1128,343 +1174,6 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key,
 }
 
 
-/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
- */
-static int
-_gnutls_asn1_encode_rsa (ASN1_TYPE * c2, bigint_t * params)
-{
-  int result;
-  opaque null = '\0';
-  gnutls_pk_params_st pk_params;
-  gnutls_datum_t m, e, d, p, q, u, exp1, exp2;
-
-  memset (&pk_params, 0, sizeof (pk_params));
-
-  memset (&m, 0, sizeof (m));
-  memset (&p, 0, sizeof (p));
-  memset (&q, 0, sizeof (q));
-  memset (&p, 0, sizeof (p));
-  memset (&u, 0, sizeof (u));
-  memset (&e, 0, sizeof (e));
-  memset (&d, 0, sizeof (d));
-  memset (&exp1, 0, sizeof (exp1));
-  memset (&exp2, 0, sizeof (exp2));
-
-  result = _gnutls_pk_params_copy (&pk_params, params, RSA_PRIVATE_PARAMS);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      return result;
-    }
-
-  result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  /* retrieve as data */
-
-  result = _gnutls_mpi_dprint_lz (pk_params.params[0], &m);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_mpi_dprint_lz (pk_params.params[1], &e);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_mpi_dprint_lz (pk_params.params[2], &d);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_mpi_dprint_lz (pk_params.params[3], &p);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_mpi_dprint_lz (pk_params.params[4], &q);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_mpi_dprint_lz (pk_params.params[5], &u);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_mpi_dprint_lz (pk_params.params[6], &exp1);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  result = _gnutls_mpi_dprint_lz (pk_params.params[7], &exp2);
-  if (result < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  /* Ok. Now we have the data. Create the asn1 structures
-   */
-
-  /* first make sure that no previously allocated data are leaked */
-  if (*c2 != ASN1_TYPE_EMPTY)
-    {
-      asn1_delete_structure (c2);
-      *c2 = ASN1_TYPE_EMPTY;
-    }
-
-  if ((result = asn1_create_element
-       (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey", c2))
-      != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  /* Write PRIME 
-   */
-  if ((result = asn1_write_value (*c2, "modulus",
-                                  m.data, m.size)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "publicExponent",
-                                  e.data, e.size)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "privateExponent",
-                                  d.data, d.size)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "prime1",
-                                  p.data, p.size)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "prime2",
-                                  q.data, q.size)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "coefficient",
-                                  u.data, u.size)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "exponent1",
-                                  exp1.data, exp1.size)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "exponent2",
-                                  exp2.data, exp2.size)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "otherPrimeInfos",
-                                  NULL, 0)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  result = 0;
-
-cleanup:
-  if (result != 0)
-    asn1_delete_structure (c2);
-
-  gnutls_pk_params_release (&pk_params);
-
-  _gnutls_free_datum (&m);
-  _gnutls_free_datum (&d);
-  _gnutls_free_datum (&e);
-  _gnutls_free_datum (&p);
-  _gnutls_free_datum (&q);
-  _gnutls_free_datum (&u);
-  _gnutls_free_datum (&exp1);
-  _gnutls_free_datum (&exp2);
-
-  return result;
-}
-
-/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
- */
-int
-_gnutls_asn1_encode_dsa (ASN1_TYPE * c2, bigint_t * params)
-{
-  int result, i;
-  size_t size[DSA_PRIVATE_PARAMS], total;
-  opaque *p_data, *q_data, *g_data, *x_data, *y_data;
-  opaque *all_data = NULL, *p;
-  opaque null = '\0';
-
-  /* Read all the sizes */
-  total = 0;
-  for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
-    {
-      _gnutls_mpi_print_lz (params[i], NULL, &size[i]);
-      total += size[i];
-    }
-
-  /* Encoding phase.
-   * allocate data enough to hold everything
-   */
-  all_data = gnutls_secure_malloc (total);
-  if (all_data == NULL)
-    {
-      gnutls_assert ();
-      result = GNUTLS_E_MEMORY_ERROR;
-      goto cleanup;
-    }
-
-  p = all_data;
-  p_data = p;
-  p += size[0];
-  q_data = p;
-  p += size[1];
-  g_data = p;
-  p += size[2];
-  y_data = p;
-  p += size[3];
-  x_data = p;
-
-  _gnutls_mpi_print_lz (params[0], p_data, &size[0]);
-  _gnutls_mpi_print_lz (params[1], q_data, &size[1]);
-  _gnutls_mpi_print_lz (params[2], g_data, &size[2]);
-  _gnutls_mpi_print_lz (params[3], y_data, &size[3]);
-  _gnutls_mpi_print_lz (params[4], x_data, &size[4]);
-
-  /* Ok. Now we have the data. Create the asn1 structures
-   */
-
-  /* first make sure that no previously allocated data are leaked */
-  if (*c2 != ASN1_TYPE_EMPTY)
-    {
-      asn1_delete_structure (c2);
-      *c2 = ASN1_TYPE_EMPTY;
-    }
-
-  if ((result = asn1_create_element
-       (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPrivateKey", c2))
-      != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  /* Write PRIME 
-   */
-  if ((result = asn1_write_value (*c2, "p", p_data, size[0])) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "q", q_data, size[1])) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "g", g_data, size[2])) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "Y", y_data, size[3])) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  if ((result = asn1_write_value (*c2, "priv",
-                                  x_data, size[4])) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  gnutls_free (all_data);
-
-  if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      result = _gnutls_asn2err (result);
-      goto cleanup;
-    }
-
-  return 0;
-
-cleanup:
-  asn1_delete_structure (c2);
-  gnutls_free (all_data);
-
-  return result;
-}
-
 
 /**
  * gnutls_x509_privkey_generate:
@@ -1487,8 +1196,6 @@ gnutls_x509_privkey_generate (gnutls_x509_privkey_t key,
                               unsigned int flags)
 {
   int ret;
-  unsigned int params_len = MAX_PRIV_PARAMS_SIZE;
-  unsigned int i;
 
   if (key == NULL)
     {
@@ -1496,74 +1203,31 @@ gnutls_x509_privkey_generate (gnutls_x509_privkey_t key,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  switch (algo)
-    {
-    case GNUTLS_PK_DSA:
-      ret = _gnutls_dsa_generate_params (key->params, &params_len, bits);
-      if (params_len != DSA_PRIVATE_PARAMS)
-        {
-          gnutls_assert ();
-          ret = GNUTLS_E_INTERNAL_ERROR;
-        }
-
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          return ret;
-        }
+  gnutls_pk_params_init(&key->params);
 
-      if (!key->crippled)
-        {
-          ret = _gnutls_asn1_encode_dsa (&key->key, key->params);
-          if (ret < 0)
-            {
-              gnutls_assert ();
-              goto cleanup;
-            }
-        }
-      key->params_size = params_len;
-      key->pk_algorithm = GNUTLS_PK_DSA;
+  ret = _gnutls_pk_generate (algo, bits, &key->params);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
 
-      break;
-    case GNUTLS_PK_RSA:
-      ret = _gnutls_rsa_generate_params (key->params, &params_len, bits);
-      if (params_len != RSA_PRIVATE_PARAMS)
-        {
-          gnutls_assert ();
-          ret = GNUTLS_E_INTERNAL_ERROR;
-        }
+  if (!key->crippled)
+    {
+      ret = _gnutls_asn1_encode_privkey (algo, &key->key, &key->params);
       if (ret < 0)
         {
           gnutls_assert ();
-          return ret;
-        }
-
-      if (!key->crippled)
-        {
-          ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
-          if (ret < 0)
-            {
-              gnutls_assert ();
-              goto cleanup;
-            }
+          goto cleanup;
         }
-
-      key->params_size = params_len;
-      key->pk_algorithm = GNUTLS_PK_RSA;
-
-      break;
-    default:
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
     }
+  key->pk_algorithm = algo;
 
   return 0;
 
 cleanup:
   key->pk_algorithm = GNUTLS_PK_UNKNOWN;
-  key->params_size = 0;
-  for (i = 0; i < params_len; i++)
-    _gnutls_mpi_release (&key->params[i]);
+  gnutls_pk_params_release(&key->params);
 
   return ret;
 }
@@ -1611,29 +1275,12 @@ gnutls_x509_privkey_get_key_id (gnutls_x509_privkey_t key,
       return GNUTLS_E_SHORT_MEMORY_BUFFER;
     }
 
-  if (key->pk_algorithm == GNUTLS_PK_RSA)
-    {
-      result =
-        _gnutls_x509_write_rsa_params (key->params, key->params_size, &der);
-      if (result < 0)
-        {
-          gnutls_assert ();
-          goto cleanup;
-        }
-    }
-  else if (key->pk_algorithm == GNUTLS_PK_DSA)
+  result = _gnutls_x509_write_pubkey(key->pk_algorithm, &key->params, &der);
+  if (result < 0)
     {
-      result =
-        _gnutls_x509_write_dsa_public_key (key->params,
-                                           key->params_size, &der);
-      if (result < 0)
-        {
-          gnutls_assert ();
-          goto cleanup;
-        }
+      gnutls_assert ();
+      goto cleanup;
     }
-  else
-    return GNUTLS_E_INTERNAL_ERROR;
 
   result = _gnutls_hash_init (&hd, GNUTLS_MAC_SHA1);
   if (result < 0)
@@ -1705,8 +1352,8 @@ _gnutls_x509_privkey_sign_hash2 (gnutls_x509_privkey_t signer,
       goto cleanup;
     }
 
-  ret = _gnutls_soft_sign (signer->pk_algorithm, signer->params,
-                           signer->params_size, &digest, signature);
+  ret = _gnutls_soft_sign (signer->pk_algorithm, &signer->params,
+                           &digest, signature);
 
   if (ret < 0)
     {
@@ -1750,8 +1397,8 @@ gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  result = _gnutls_soft_sign (key->pk_algorithm, key->params,
-                              key->params_size, hash, signature);
+  result = _gnutls_soft_sign (key->pk_algorithm, &key->params,
+                              hash, signature);
   if (result < 0)
     {
       gnutls_assert ();
@@ -1806,7 +1453,7 @@ gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key,
     }
 
   result =
-    pk_hash_data (key->pk_algorithm, digest, key->params, data, &hash);
+    pk_hash_data (key->pk_algorithm, digest, &key->params, data, &hash);
   if (result < 0)
     {
       gnutls_assert ();
@@ -1902,27 +1549,12 @@ gnutls_x509_privkey_fix (gnutls_x509_privkey_t key)
 
   if (!key->crippled)
     asn1_delete_structure (&key->key);
-  switch (key->pk_algorithm)
+
+  ret = _gnutls_asn1_encode_privkey (key->pk_algorithm, &key->key, &key->params);
+  if (ret < 0)
     {
-    case GNUTLS_PK_DSA:
-      ret = _gnutls_asn1_encode_dsa (&key->key, key->params);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          return ret;
-        }
-      break;
-    case GNUTLS_PK_RSA:
-      ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          return ret;
-        }
-      break;
-    default:
       gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
+      return ret;
     }
 
   return 0;
index 47059d5679464135c107bbcf3f6ce202ac581e50..5ef565deb43225a492b0efd920c1fd8ae5b2e051 100644 (file)
@@ -40,6 +40,8 @@
 #include <random.h>
 #include <pbkdf2-sha1.h>
 
+static int _decode_pkcs8_ecc_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey);
+
 #define PBES2_OID "1.2.840.113549.1.5.13"
 #define PBKDF2_OID "1.2.840.113549.1.5.12"
 #define DES_EDE3_CBC_OID "1.2.840.113549.3.7"
@@ -140,6 +142,7 @@ _encode_privkey (gnutls_x509_privkey_t pkey, gnutls_datum_t * raw)
   switch (pkey->pk_algorithm)
     {
     case GNUTLS_PK_RSA:
+    case GNUTLS_PK_ECC:
       ret =
         gnutls_x509_privkey_export (pkey, GNUTLS_X509_FMT_DER, NULL, &size);
       if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
@@ -178,7 +181,7 @@ _encode_privkey (gnutls_x509_privkey_t pkey, gnutls_datum_t * raw)
           return _gnutls_asn2err (ret);
         }
 
-      ret = _gnutls_x509_write_int (spk, "", pkey->params[4], 1);
+      ret = _gnutls_x509_write_int (spk, "", pkey->params.params[4], 1);
       if (ret < 0)
         {
           gnutls_assert ();
@@ -223,30 +226,19 @@ encode_to_private_key_info (gnutls_x509_privkey_t pkey,
   gnutls_datum_t algo_params = { NULL, 0 };
   gnutls_datum_t algo_privkey = { NULL, 0 };
 
-  if (pkey->pk_algorithm != GNUTLS_PK_RSA
-      && pkey->pk_algorithm != GNUTLS_PK_DSA)
+  oid = _gnutls_x509_pk_to_oid(pkey->pk_algorithm);
+  if (oid == NULL)
     {
       gnutls_assert ();
       return GNUTLS_E_UNIMPLEMENTED_FEATURE;
     }
 
-  if (pkey->pk_algorithm == GNUTLS_PK_RSA)
-    {
-      oid = PK_PKIX1_RSA_OID;
-      /* parameters are null 
-       */
-    }
-  else
+  result =
+      _gnutls_x509_write_pubkey_params (pkey->pk_algorithm, &pkey->params, &algo_params);
+  if (result < 0)
     {
-      oid = PK_DSA_OID;
-      result =
-        _gnutls_x509_write_dsa_params (pkey->params, pkey->params_size,
-                                       &algo_params);
-      if (result < 0)
-        {
-          gnutls_assert ();
-          return result;
-        }
+      gnutls_assert ();
+      return result;
     }
 
   if ((result =
@@ -986,6 +978,36 @@ error:
   return ret;
 }
 
+/* Decodes an ECC privateKey from a PKCS8 structure.
+ */
+static int
+_decode_pkcs8_ecc_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey)
+{
+  int ret;
+  gnutls_datum_t tmp;
+
+  ret = _gnutls_x509_read_value (pkcs8_asn, "privateKey", &tmp, 0);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto error;
+    }
+
+  pkey->key = _gnutls_privkey_decode_ecc_key (&tmp, pkey);
+  _gnutls_free_datum (&tmp);
+  if (pkey->key == NULL)
+    {
+      gnutls_assert ();
+      goto error;
+    }
+
+  return 0;
+
+error:
+  gnutls_x509_privkey_deinit (pkey);
+  return ret;
+}
+
 /* Decodes an DSA privateKey and params from a PKCS8 structure.
  */
 static int
@@ -1001,7 +1023,7 @@ _decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey)
       goto error;
     }
 
-  ret = _gnutls_x509_read_der_int (tmp.data, tmp.size, &pkey->params[4]);
+  ret = _gnutls_x509_read_der_int (tmp.data, tmp.size, &pkey->params.params[4]);
   _gnutls_free_datum (&tmp);
 
   if (ret < 0)
@@ -1019,7 +1041,7 @@ _decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey)
       goto error;
     }
 
-  ret = _gnutls_x509_read_dsa_params (tmp.data, tmp.size, pkey->params);
+  ret = _gnutls_x509_read_pubkey_params (GNUTLS_PK_DSA, tmp.data, tmp.size, &pkey->params);
   _gnutls_free_datum (&tmp);
   if (ret < 0)
     {
@@ -1028,19 +1050,19 @@ _decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey)
     }
 
   /* the public key can be generated as g^x mod p */
-  pkey->params[3] = _gnutls_mpi_alloc_like (pkey->params[0]);
-  if (pkey->params[3] == NULL)
+  pkey->params.params[3] = _gnutls_mpi_alloc_like (pkey->params.params[0]);
+  if (pkey->params.params[3] == NULL)
     {
       gnutls_assert ();
       goto error;
     }
 
-  _gnutls_mpi_powm (pkey->params[3], pkey->params[2], pkey->params[4],
-                    pkey->params[0]);
+  _gnutls_mpi_powm (pkey->params.params[3], pkey->params.params[2], pkey->params.params[4],
+                    pkey->params.params[0]);
 
   if (!pkey->crippled)
     {
-      ret = _gnutls_asn1_encode_dsa (&pkey->key, pkey->params);
+      ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_DSA, &pkey->key, &pkey->params);
       if (ret < 0)
         {
           gnutls_assert ();
@@ -1048,7 +1070,7 @@ _decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey)
         }
     }
 
-  pkey->params_size = DSA_PRIVATE_PARAMS;
+  pkey->params.params_nr = DSA_PRIVATE_PARAMS;
 
   return 0;
 
@@ -1099,11 +1121,9 @@ decode_private_key_info (const gnutls_datum_t * der,
 
   /* we only support RSA and DSA private keys.
    */
-  if (strcmp (oid, PK_PKIX1_RSA_OID) == 0)
-    pkey->pk_algorithm = GNUTLS_PK_RSA;
-  else if (strcmp (oid, PK_DSA_OID) == 0)
-    pkey->pk_algorithm = GNUTLS_PK_DSA;
-  else
+
+  pkey->pk_algorithm = _gnutls_x509_oid2pk_algorithm(oid);
+  if (pkey->pk_algorithm == GNUTLS_PK_UNKNOWN)
     {
       gnutls_assert ();
       _gnutls_debug_log
@@ -1119,6 +1139,9 @@ decode_private_key_info (const gnutls_datum_t * der,
     result = _decode_pkcs8_rsa_key (pkcs8_asn, pkey);
   else if (pkey->pk_algorithm == GNUTLS_PK_DSA)
     result = _decode_pkcs8_dsa_key (pkcs8_asn, pkey);
+  else if (pkey->pk_algorithm == GNUTLS_PK_ECC)
+    result = _decode_pkcs8_ecc_key (pkcs8_asn, pkey);
+  else return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
 
   if (result < 0)
     {
index 5a9db51cda337ed15f5ec278943df59879f1b285..747405ff4103e4d86f1184e0460fbad2e8f166ce 100644 (file)
@@ -752,8 +752,8 @@ decode_ber_digest_info (const gnutls_datum_t * info,
 static int
 _pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
                        const gnutls_datum_t * prehash,
-                       const gnutls_datum_t * signature, bigint_t * params,
-                       int params_len)
+                       const gnutls_datum_t * signature, 
+                       gnutls_pk_params_st * params)
 {
   gnutls_mac_algorithm_t hash = GNUTLS_MAC_UNKNOWN;
   int ret;
@@ -763,7 +763,7 @@ _pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
   gnutls_datum_t decrypted;
 
   ret =
-    _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, params_len, 1);
+    _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, 1);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -829,8 +829,8 @@ _pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
 static int
 dsa_verify_sig (const gnutls_datum_t * text,
                 const gnutls_datum_t * hash,
-                const gnutls_datum_t * signature, bigint_t * params,
-                int params_len)
+                const gnutls_datum_t * signature,
+                gnutls_pk_params_st* params)
 {
   int ret;
   opaque _digest[MAX_HASH_SIZE];
@@ -838,7 +838,7 @@ dsa_verify_sig (const gnutls_datum_t * text,
   digest_hd_st hd;
   gnutls_digest_algorithm_t algo;
 
-  algo = _gnutls_dsa_q_to_hash (params[1]);
+  algo = _gnutls_dsa_q_to_hash (params->params[1]);
   if (hash)
     {
       /* SHA1 or better allowed */
@@ -867,7 +867,7 @@ dsa_verify_sig (const gnutls_datum_t * text,
       digest.size = _gnutls_hash_get_algo_len(algo);
     }
 
-  ret = _gnutls_dsa_verify (&digest, signature, params, params_len);
+  ret = _gnutls_dsa_verify (&digest, signature, params);
 
   return ret;
 }
@@ -879,8 +879,8 @@ int
 pubkey_verify_sig (const gnutls_datum_t * tbs,
                    const gnutls_datum_t * hash,
                    const gnutls_datum_t * signature,
-                   gnutls_pk_algorithm_t pk, bigint_t * issuer_params,
-                   int issuer_params_size)
+                   gnutls_pk_algorithm_t pk,
+                   gnutls_pk_params_st * issuer_params)
 {
 
   switch (pk)
@@ -888,7 +888,7 @@ pubkey_verify_sig (const gnutls_datum_t * tbs,
     case GNUTLS_PK_RSA:
 
       if (_pkcs1_rsa_verify_sig
-          (tbs, hash, signature, issuer_params, issuer_params_size) != 0)
+          (tbs, hash, signature, issuer_params) != 0)
         {
           gnutls_assert ();
           return GNUTLS_E_PK_SIG_VERIFY_FAILED;
@@ -899,7 +899,7 @@ pubkey_verify_sig (const gnutls_datum_t * tbs,
 
     case GNUTLS_PK_DSA:
       if (dsa_verify_sig
-          (tbs, hash, signature, issuer_params, issuer_params_size) != 0)
+          (tbs, hash, signature, issuer_params) != 0)
         {
           gnutls_assert ();
           return GNUTLS_E_PK_SIG_VERIFY_FAILED;
@@ -941,8 +941,7 @@ int
 _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
                                const gnutls_datum_t * signature,
                                gnutls_pk_algorithm_t pk,
-                               bigint_t * issuer_params,
-                               unsigned int issuer_params_size)
+                               gnutls_pk_params_st * issuer_params)
 {
   opaque digest[MAX_HASH_SIZE];
   gnutls_datum_t decrypted;
@@ -954,7 +953,7 @@ _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
     case GNUTLS_PK_DSA:
 
       if (hash)
-        *hash = _gnutls_dsa_q_to_hash (issuer_params[1]);
+        *hash = _gnutls_dsa_q_to_hash (issuer_params->params[1]);
 
       ret = 0;
       break;
@@ -968,7 +967,7 @@ _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
 
       ret =
         _gnutls_pkcs1_rsa_decrypt (&decrypted, signature,
-                                   issuer_params, issuer_params_size, 1);
+                                   issuer_params, 1);
 
 
       if (ret < 0)
@@ -1021,14 +1020,13 @@ _gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
                                const gnutls_datum_t * signature,
                                gnutls_x509_crt_t issuer)
 {
-  bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE];
-  int ret, issuer_params_size, i;
+  gnutls_pk_params_st issuer_params;
+  int ret;
 
   /* Read the MPI parameters from the issuer's certificate.
    */
-  issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
   ret =
-    _gnutls_x509_crt_get_mpis (issuer, issuer_params, &issuer_params_size);
+    _gnutls_x509_crt_get_mpis (issuer, &issuer_params);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1038,7 +1036,7 @@ _gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
   ret =
     pubkey_verify_sig (tbs, hash, signature,
                        gnutls_x509_crt_get_pk_algorithm (issuer, NULL),
-                       issuer_params, issuer_params_size);
+                       &issuer_params);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1046,10 +1044,7 @@ _gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
 
   /* release all allocated MPIs
    */
-  for (i = 0; i < issuer_params_size; i++)
-    {
-      _gnutls_mpi_release (&issuer_params[i]);
-    }
+  gnutls_pk_params_release(&issuer_params);
 
   return ret;
 }
@@ -1068,7 +1063,7 @@ _gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs,
   int ret;
 
   ret = pubkey_verify_sig (tbs, NULL, signature, issuer->pk_algorithm,
-                           issuer->params, issuer->params_size);
+                           &issuer->params);
   if (ret < 0)
     {
       gnutls_assert ();
index ee97a5cebd64d5634043bfd54fb5dbb1995560e9..810057a0491816259a3493be5417719ee2a5682b 100644 (file)
@@ -2190,8 +2190,8 @@ gnutls_x509_crt_export (gnutls_x509_crt_t cert,
 }
 
 int
-_gnutls_get_key_id (gnutls_pk_algorithm_t pk, bigint_t * params,
-                    int params_size, unsigned char *output_data,
+_gnutls_get_key_id (gnutls_pk_algorithm_t pk, gnutls_pk_params_st * params,
+                    unsigned char *output_data,
                     size_t * output_data_size)
 {
   int result = 0;
@@ -2205,26 +2205,12 @@ _gnutls_get_key_id (gnutls_pk_algorithm_t pk, bigint_t * params,
       return GNUTLS_E_SHORT_MEMORY_BUFFER;
     }
 
-  if (pk == GNUTLS_PK_RSA)
-    {
-      result = _gnutls_x509_write_rsa_params (params, params_size, &der);
-      if (result < 0)
-        {
-          gnutls_assert ();
-          goto cleanup;
-        }
-    }
-  else if (pk == GNUTLS_PK_DSA)
+  result = _gnutls_x509_write_pubkey(pk, params, &der);
+  if (result < 0)
     {
-      result = _gnutls_x509_write_dsa_public_key (params, params_size, &der);
-      if (result < 0)
-        {
-          gnutls_assert ();
-          goto cleanup;
-        }
+      gnutls_assert ();
+      goto cleanup;
     }
-  else
-    return GNUTLS_E_INTERNAL_ERROR;
 
   result = _gnutls_hash_init (&hd, GNUTLS_MAC_SHA1);
   if (result < 0)
@@ -2251,11 +2237,10 @@ static int
 rsadsa_get_key_id (gnutls_x509_crt_t crt, int pk,
                    unsigned char *output_data, size_t * output_data_size)
 {
-  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
-  int params_size = MAX_PUBLIC_PARAMS_SIZE;
-  int i, result = 0;
+  gnutls_pk_params_st params;
+  int result = 0;
 
-  result = _gnutls_x509_crt_get_mpis (crt, params, &params_size);
+  result = _gnutls_x509_crt_get_mpis (crt, &params);
   if (result < 0)
     {
       gnutls_assert ();
@@ -2263,7 +2248,7 @@ rsadsa_get_key_id (gnutls_x509_crt_t crt, int pk,
     }
 
   result =
-    _gnutls_get_key_id (pk, params, params_size, output_data,
+    _gnutls_get_key_id (pk, &params, output_data,
                         output_data_size);
   if (result < 0)
     {
@@ -2277,10 +2262,7 @@ cleanup:
 
   /* release all allocated MPIs
    */
-  for (i = 0; i < params_size; i++)
-    {
-      _gnutls_mpi_release (&params[i]);
-    }
+  gnutls_pk_params_release(&params);
   return result;
 }
 
@@ -2524,9 +2506,8 @@ gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt,
                                       const gnutls_datum_t * signature,
                                       gnutls_digest_algorithm_t * hash)
 {
-  bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE];
-  int issuer_params_size;
-  int ret, i;
+  gnutls_pk_params_st issuer_params;
+  int ret;
 
   if (crt == NULL)
     {
@@ -2534,8 +2515,7 @@ gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
-  ret = _gnutls_x509_crt_get_mpis (crt, issuer_params, &issuer_params_size);
+  ret = _gnutls_x509_crt_get_mpis (crt, &issuer_params);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -2546,13 +2526,10 @@ gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt,
                                        signature,
                                        gnutls_x509_crt_get_pk_algorithm (crt,
                                                                          NULL),
-                                       issuer_params, issuer_params_size);
+                                       &issuer_params);
 
   /* release allocated mpis */
-  for (i = 0; i < issuer_params_size; i++)
-    {
-      _gnutls_mpi_release (&issuer_params[i]);
-    }
+  gnutls_pk_params_release(&issuer_params);
 
   return ret;
 }
@@ -2581,9 +2558,8 @@ gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt,
                                               gnutls_digest_algorithm_t *
                                               hash, unsigned int *mand)
 {
-  bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE];
-  int issuer_params_size;
-  int ret, i;
+  gnutls_pk_params_st issuer_params;
+  int ret;
 
   if (crt == NULL)
     {
@@ -2591,8 +2567,7 @@ gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
-  ret = _gnutls_x509_crt_get_mpis (crt, issuer_params, &issuer_params_size);
+  ret = _gnutls_x509_crt_get_mpis (crt, &issuer_params);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -2601,14 +2576,11 @@ gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt,
 
   ret =
     _gnutls_pk_get_hash_algorithm (gnutls_x509_crt_get_pk_algorithm
-                                   (crt, NULL), issuer_params,
-                                   issuer_params_size, hash, mand);
+                                   (crt, NULL), &issuer_params,
+                                   hash, mand);
 
   /* release allocated mpis */
-  for (i = 0; i < issuer_params_size; i++)
-    {
-      _gnutls_mpi_release (&issuer_params[i]);
-    }
+  gnutls_pk_params_release(&issuer_params);
 
   return ret;
 }
@@ -2936,9 +2908,7 @@ gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt,
                                 gnutls_datum_t * m, gnutls_datum_t * e)
 {
   int ret;
-  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
-  int params_size = MAX_PUBLIC_PARAMS_SIZE;
-  int i;
+  gnutls_pk_params_st params;
 
   if (crt == NULL)
     {
@@ -2953,21 +2923,21 @@ gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  ret = _gnutls_x509_crt_get_mpis (crt, params, &params_size);
+  ret = _gnutls_x509_crt_get_mpis (crt, &params);
   if (ret < 0)
     {
       gnutls_assert ();
       return ret;
     }
 
-  ret = _gnutls_mpi_dprint_lz (params[0], m);
+  ret = _gnutls_mpi_dprint_lz (params.params[0], m);
   if (ret < 0)
     {
       gnutls_assert ();
       goto cleanup;
     }
 
-  ret = _gnutls_mpi_dprint_lz (params[1], e);
+  ret = _gnutls_mpi_dprint_lz (params.params[1], e);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -2978,10 +2948,7 @@ gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt,
   ret = 0;
 
 cleanup:
-  for (i = 0; i < params_size; i++)
-    {
-      _gnutls_mpi_release (&params[i]);
-    }
+  gnutls_pk_params_release(&params);
   return ret;
 }
 
@@ -3005,9 +2972,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
                                 gnutls_datum_t * g, gnutls_datum_t * y)
 {
   int ret;
-  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
-  int params_size = MAX_PUBLIC_PARAMS_SIZE;
-  int i;
+  gnutls_pk_params_st params;
 
   if (crt == NULL)
     {
@@ -3022,7 +2987,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  ret = _gnutls_x509_crt_get_mpis (crt, params, &params_size);
+  ret = _gnutls_x509_crt_get_mpis (crt, &params);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -3031,7 +2996,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
 
 
   /* P */
-  ret = _gnutls_mpi_dprint_lz (params[0], p);
+  ret = _gnutls_mpi_dprint_lz (params.params[0], p);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -3039,7 +3004,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
     }
 
   /* Q */
-  ret = _gnutls_mpi_dprint_lz (params[1], q);
+  ret = _gnutls_mpi_dprint_lz (params.params[1], q);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -3049,7 +3014,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
 
 
   /* G */
-  ret = _gnutls_mpi_dprint_lz (params[2], g);
+  ret = _gnutls_mpi_dprint_lz (params.params[2], g);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -3060,7 +3025,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
 
 
   /* Y */
-  ret = _gnutls_mpi_dprint_lz (params[3], y);
+  ret = _gnutls_mpi_dprint_lz (params.params[3], y);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -3073,10 +3038,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
   ret = 0;
 
 cleanup:
-  for (i = 0; i < params_size; i++)
-    {
-      _gnutls_mpi_release (&params[i]);
-    }
+  gnutls_pk_params_release(&params);
   return ret;
 
 }
index ce9faae58de31e8310abf6766f2af92fdefa21ad..95132ff67c5674641d1647dc938257389daffaa7 100644 (file)
@@ -78,7 +78,7 @@ typedef struct gnutls_pkcs7_int
 /* parameters should not be larger than this limit */
 #define DSA_PUBLIC_PARAMS 4
 #define RSA_PUBLIC_PARAMS 2
-#define ECDH_PUBLIC_PARAMS 8
+#define ECC_PUBLIC_PARAMS 8
 
 
 #define MAX_PRIV_PARAMS_SIZE GNUTLS_MAX_PK_PARAMS       /* ok for RSA and DSA */
@@ -86,12 +86,16 @@ typedef struct gnutls_pkcs7_int
 /* parameters should not be larger than this limit */
 #define DSA_PRIVATE_PARAMS 5
 #define RSA_PRIVATE_PARAMS 8
-#define ECDH_PRIVATE_PARAMS 9
+#define ECC_PRIVATE_PARAMS 9
 
 #if MAX_PRIV_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0
 #error INCREASE MAX_PRIV_PARAMS
 #endif
 
+#if MAX_PRIV_PARAMS_SIZE - ECC_PRIVATE_PARAMS < 0
+#error INCREASE MAX_PRIV_PARAMS
+#endif
+
 #if MAX_PRIV_PARAMS_SIZE - DSA_PRIVATE_PARAMS < 0
 #error INCREASE MAX_PRIV_PARAMS
 #endif
@@ -101,29 +105,7 @@ typedef struct gnutls_x509_privkey_int
   /* the size of params depends on the public
    * key algorithm
    */
-  bigint_t params[MAX_PRIV_PARAMS_SIZE];
-
-  /*
-   * RSA: [0] is modulus
-   *      [1] is public exponent
-   *      [2] is private exponent
-   *      [3] is prime1 (p)
-   *      [4] is prime2 (q)
-   *      [5] is coefficient (u == inverse of p mod q)
-   *          note that other packages used inverse of q mod p,
-   *          so we need to perform conversions on import/export
-   *          using fixup.
-   *      The following two are also not always available thus fixup
-   *      will generate them.
-   *      [6] e1 == d mod (p-1)
-   *      [7] e2 == d mod (q-1)
-   * DSA: [0] is p
-   *      [1] is q
-   *      [2] is g
-   *      [3] is y (public key)
-   *      [4] is x (private key)
-   */
-  int params_size;              /* holds the number of params */
+  gnutls_pk_params_st params;
 
   gnutls_pk_algorithm_t pk_algorithm;
 
@@ -198,8 +180,7 @@ int
 _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
                                const gnutls_datum_t * signature,
                                gnutls_pk_algorithm_t pk,
-                               bigint_t * issuer_params,
-                               unsigned int issuer_params_size);
+                               gnutls_pk_params_st * issuer_params);
 
 int _gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
                                    const gnutls_datum_t * hash,
@@ -213,7 +194,10 @@ int _gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs,
 ASN1_TYPE _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t *
                                                 raw_key,
                                                 gnutls_x509_privkey_t pkey);
-int _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, bigint_t * params);
+ASN1_TYPE _gnutls_privkey_decode_ecc_key (const gnutls_datum_t *
+                                                raw_key,
+                                                gnutls_x509_privkey_t pkey);
+int _gnutls_asn1_encode_privkey (gnutls_pk_algorithm_t pk, ASN1_TYPE * c2, gnutls_pk_params_st * params);
 
 /* extensions.c */
 int _gnutls_x509_crl_get_extension (gnutls_x509_crl_t crl,
@@ -288,22 +272,22 @@ int _gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint,
 
 /* mpi.c */
 int _gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert,
-                               bigint_t * params, int *params_size);
+                               gnutls_pk_params_st*);
 
 int _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
-                               bigint_t * params, int *params_size);
-int _gnutls_x509_read_rsa_params (opaque * der, int dersize,
-                                  bigint_t * params);
-int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize,
-                                  bigint_t * params);
-int _gnutls_x509_read_dsa_params (opaque * der, int dersize,
-                                  bigint_t * params);
-
-int _gnutls_x509_write_rsa_params (bigint_t * params, int params_size,
-                                   gnutls_datum_t * der);
-int _gnutls_x509_write_dsa_params (bigint_t * params, int params_size,
+                               gnutls_pk_params_st * params);
+
+int _gnutls_x509_read_pubkey_params (gnutls_pk_algorithm_t, opaque * der, int dersize,
+                                  gnutls_pk_params_st * params);
+
+int _gnutls_x509_read_pubkey (gnutls_pk_algorithm_t, opaque * der, int dersize,
+                                  gnutls_pk_params_st * params);
+
+int
+_gnutls_x509_write_pubkey_params (gnutls_pk_algorithm_t algo,
+                                   gnutls_pk_params_st* params,
                                    gnutls_datum_t * der);
-int _gnutls_x509_write_dsa_public_key (bigint_t * params, int params_size,
+int _gnutls_x509_write_pubkey (gnutls_pk_algorithm_t, gnutls_pk_params_st * params,
                                        gnutls_datum_t * der);
 
 int _gnutls_x509_read_uint (ASN1_TYPE node, const char *value,
index 68f010367066313af6a906aa820b59d1c4b62a3b..45c3e74864675e19bd09f4cba695fafe5ea8d8ae 100644 (file)
@@ -233,8 +233,7 @@ gnutls_x509_crt_set_key (gnutls_x509_crt_t crt, gnutls_x509_privkey_t key)
   result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert,
                                                     "tbsCertificate.subjectPublicKeyInfo",
                                                     key->pk_algorithm,
-                                                    key->params,
-                                                    key->params_size);
+                                                    &key->params);
 
   if (result < 0)
     {