]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
print information on ECC certificates.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 22 May 2011 13:59:58 +0000 (15:59 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 22 May 2011 13:59:58 +0000 (15:59 +0200)
lib/algorithms/secparams.c
lib/gnutls_pubkey.c
lib/includes/gnutls/abstract.h
lib/libgnutls.map
lib/x509/common.c
lib/x509/key_decode.c
lib/x509/mpi.c
lib/x509/output.c

index 35969b3feb05ea18463dd7501053ca91823aa67e..09dd2401f4065279a9938cd7dcce052d8172d812 100644 (file)
@@ -83,14 +83,25 @@ gnutls_sec_param_to_pk_bits (gnutls_pk_algorithm_t algo,
       );
       return ret;
     }
-
-  GNUTLS_SEC_PARAM_LOOP (if (p->sec_param == param)
+  else if (algo == GNUTLS_PK_ECC)
+    {
+      GNUTLS_SEC_PARAM_LOOP (if (p->sec_param == param)
+                             {
+                               ret = p->ecc_bits; break;
+                             }
+      );
+      return ret;
+    }
+  else
+    {
+      GNUTLS_SEC_PARAM_LOOP (if (p->sec_param == param)
                          {
                            ret = p->pk_bits; break;
                          }
-  );
+      );
 
-  return ret;
+      return ret;
+    }
 }
 
 /* Returns the corresponding size for subgroup bits (q),
@@ -149,13 +160,24 @@ gnutls_sec_param_get_name (gnutls_sec_param_t param)
 gnutls_sec_param_t
 gnutls_pk_bits_to_sec_param (gnutls_pk_algorithm_t algo, unsigned int bits)
 {
-  gnutls_sec_param_t ret = GNUTLS_SEC_PARAM_WEAK;
+  gnutls_sec_param_t ret = GNUTLS_SEC_PARAM_UNKNOWN;
 
-  GNUTLS_SEC_PARAM_LOOP (if (p->pk_bits > bits)
+  if (algo == GNUTLS_PK_ECC)
+    {
+      GNUTLS_SEC_PARAM_LOOP (if (p->ecc_bits > bits)
+                         {
+                           break;
+                         }
+                         ret = p->sec_param;);
+    }
+  else
+    {
+      GNUTLS_SEC_PARAM_LOOP (if (p->pk_bits > bits)
                          {
                            break;
                          }
                          ret = p->sec_param;);
+    }
 
   return ret;
 }
index c6ad39abc8a531ea3ed7fb93a01a9ed95ee3e90c..c75f7f80a92f5fe250c6136f7dac9a2f34d98310 100644 (file)
@@ -672,6 +672,59 @@ gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key,
   return 0;
 }
 
+/**
+ * gnutls_pubkey_get_pk_ecc_raw:
+ * @key: Holds the public key
+ * @curve: will hold the curve
+ * @x: will hold x
+ * @y: will hold y
+ *
+ * This function will export the ECC public key's parameters found in
+ * the given certificate.  The new parameters will be allocated using
+ * gnutls_malloc() and will be stored in the appropriate datum.
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
+ **/
+int
+gnutls_pubkey_get_pk_ecc_raw (gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
+                              gnutls_datum_t * x, gnutls_datum_t * y)
+{
+  int ret;
+
+  if (key == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  if (key->pk_algorithm != GNUTLS_PK_ECC)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  *curve = key->params.flags;
+
+  /* X */
+  ret = _gnutls_mpi_dprint (key->params.params[5], x);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  /* Y */
+  ret = _gnutls_mpi_dprint (key->params.params[6], y);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      _gnutls_free_datum (x);
+      return ret;
+    }
+
+  return 0;
+}
+
 /**
  * gnutls_pubkey_import:
  * @key: The structure to store the parsed public key. 
index 3c6274fc213a9937ffe381ddeb698028b6eef147..ba097b0b6945da14c1e42542e85fb2c9fa75fe6d 100644 (file)
@@ -40,6 +40,8 @@ int gnutls_pubkey_get_pk_rsa_raw (gnutls_pubkey_t key,
 int gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key,
                                   gnutls_datum_t * p, gnutls_datum_t * q,
                                   gnutls_datum_t * g, gnutls_datum_t * y);
+int gnutls_pubkey_get_pk_ecc_raw (gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
+                              gnutls_datum_t * x, gnutls_datum_t * y);
 
 int gnutls_pubkey_export (gnutls_pubkey_t key,
                           gnutls_x509_crt_fmt_t format,
index 1fe7dcfd9ca5b28c2a9116b842947616422ecdf8..a26bb5b73f7943af4e5fa10915dd82bf0d567ed5 100644 (file)
@@ -715,6 +715,7 @@ GNUTLS_3_0_0 {
        gnutls_global_set_audit_log_function;
        gnutls_ecc_curve_get_name;
        gnutls_ecc_curve_get_size;
+       gnutls_pubkey_get_pk_ecc_raw;
 } GNUTLS_2_12;
 
 GNUTLS_PRIVATE {
index 9bbfd387bcfcb9e5c90898bb3d1c8a1f644db158..3395834091cf4a56f277f081031e594f2bb727c2 100644 (file)
@@ -1259,7 +1259,6 @@ _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
                                unsigned int *bits)
 {
   int result;
-  opaque *str = NULL;
   int algo;
   char oid[64];
   int len;
@@ -1292,52 +1291,13 @@ _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
 
   /* Now read the parameters' bits 
    */
-  _asnstr_append_name (name, sizeof (name), src_name, ".subjectPublicKey");
-
-  len = 0;
-  result = asn1_read_value (src, name, NULL, &len);
-  if (result != ASN1_MEM_ERROR)
-    {
-      gnutls_assert ();
-      return _gnutls_asn2err (result);
-    }
-
-  if (len % 8 != 0)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_CERTIFICATE_ERROR;
-    }
-
-  len /= 8;
-
-  str = gnutls_malloc (len);
-  if (str == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  _asnstr_append_name (name, sizeof (name), src_name, ".subjectPublicKey");
-
-  result = asn1_read_value (src, name, str, &len);
-
-  if (result != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      gnutls_free (str);
-      return _gnutls_asn2err (result);
-    }
-
-  len /= 8;
-
-  result = _gnutls_x509_read_pubkey (algo, str, len, &params);
+  result = _gnutls_get_asn_mpis(src, src_name, &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 e2b56b538b130a7d2bdcf3b7af4c06397cf61638..d0bbce1b459dd5f97e62b28059cee9dfde74b878 100644 (file)
@@ -104,23 +104,43 @@ _gnutls_x509_read_rsa_pubkey (opaque * der, int dersize, gnutls_pk_params_st * p
 int
 _gnutls_x509_read_ecc_pubkey (opaque * der, int dersize, gnutls_pk_params_st * params)
 {
-  uint8_t* octet;
+#if 0  
   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);
+  ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+  gnutls_datum_t octet;
+
+  if ((ret = asn1_create_element
+       (_gnutls_get_gnutls_asn (), "GNUTLS.ECPoint", &spk))
+      != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (ret);
+    }
+
+  ret = asn1_der_decoding (&spk, der, dersize, NULL);
+  if (ret != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&spk);
+      return _gnutls_asn2err (ret);
+    }
+
+
+  if ((ret = _gnutls_x509_read_value (spk, "", &octet, 0)) < 0)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&spk);
+      return GNUTLS_E_ASN1_GENERIC_ERROR;
+    }
 
-  ret = _gnutls_ecc_ansi_x963_import (octet, octet_size, &params->params[5],
+  ret = _gnutls_ecc_ansi_x963_import (octet.data, octet.size, &params->params[5],
                                      &params->params[6]);
-  gnutls_free(octet);
+  _gnutls_free_datum(&octet);
   
   return ret;
+#endif
+  return _gnutls_ecc_ansi_x963_import (der, dersize, &params->params[5],
+                                     &params->params[6]);
 }
 
 
@@ -237,7 +257,7 @@ _gnutls_x509_read_ecc_params (opaque * der, int dersize, gnutls_pk_params_st * p
       ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
       goto cleanup;
     }
-    
+
   ret = _gnutls_ecc_curve_fill_params(params->flags, params);
   if (ret < 0)
     {
@@ -258,17 +278,27 @@ cleanup:
 int _gnutls_x509_read_pubkey (gnutls_pk_algorithm_t algo, opaque * der, int dersize,
                                   gnutls_pk_params_st * params)
 {
+int ret;
+
   switch(algo)
     {
       case GNUTLS_PK_RSA:
-        return _gnutls_x509_read_rsa_pubkey(der, dersize, params);
+        ret = _gnutls_x509_read_rsa_pubkey(der, dersize, params);
+        if (ret >= 0) params->params_nr = RSA_PUBLIC_PARAMS;
+        break;
       case GNUTLS_PK_DSA:
-        return _gnutls_x509_read_dsa_pubkey(der, dersize, params);
+        ret = _gnutls_x509_read_dsa_pubkey(der, dersize, params);
+        if (ret >= 0) params->params_nr = DSA_PUBLIC_PARAMS;
+        break;
       case GNUTLS_PK_ECC:
-        return _gnutls_x509_read_ecc_pubkey(der, dersize, params);
+        ret = _gnutls_x509_read_ecc_pubkey(der, dersize, params);
+        if (ret >= 0) params->params_nr = ECC_PUBLIC_PARAMS;
+        break;
       default:
-        return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
+        ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
+        break;
     }
+  return ret;
 }
 
 int _gnutls_x509_read_pubkey_params (gnutls_pk_algorithm_t algo, opaque * der, int dersize,
index b57e7988a8c251c38fe5bd67d2b3ff062ff32807..37a83869469470ef80882e30628812b01be6a4b8 100644 (file)
@@ -123,24 +123,27 @@ _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root,
  
   _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.
    */
 
-  if (result < 0 && pk_algorithm != GNUTLS_PK_RSA) /* RSA doesn't use parameters */
+  if (pk_algorithm != GNUTLS_PK_RSA) /* RSA doesn't use parameters */
     {
-      gnutls_assert ();
-      goto error;
-    }
-
-  if ((result =
-       _gnutls_x509_read_pubkey_params (pk_algorithm, tmp.data, tmp.size, params)) < 0)
-    {
-      gnutls_assert ();
-      goto error;
+      result = _gnutls_x509_read_value (asn, name, &tmp, 0);
+      if (result < 0) 
+        {
+          gnutls_assert ();
+          goto error;
+        }
+
+      if ((result =
+           _gnutls_x509_read_pubkey_params (pk_algorithm, tmp.data, tmp.size, params)) < 0)
+        {
+          gnutls_assert ();
+          goto error;
+        }
     }
 
   result = 0;
index a49ae9543f044175b3fe78ddb093106d91e0bac4..3977596bc4f3af7501b68c9d7dd33fcecb1e23b1 100644 (file)
@@ -1147,7 +1147,7 @@ print_cert (gnutls_buffer_st * str, gnutls_x509_crt_t cert, int notsigned)
 
   /* SubjectPublicKeyInfo. */
   {
-    int err;
+    int err, pk;
     unsigned int bits;
 
     err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
@@ -1155,23 +1155,39 @@ print_cert (gnutls_buffer_st * str, gnutls_x509_crt_t cert, int notsigned)
       addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
     else
       {
+        gnutls_pubkey_t pubkey;
         const char *name = gnutls_pk_algorithm_get_name (err);
         if (name == NULL)
           name = _("unknown");
+          
+        pk = err;
 
         addf (str, _("\tSubject Public Key Algorithm: %s\n"), name);
         addf (str, _("\tCertificate Security Level: %s\n"),
               gnutls_sec_param_get_name (gnutls_pk_bits_to_sec_param
                                          (err, bits)));
-
 #ifdef ENABLE_PKI
-        switch (err)
+        err = gnutls_pubkey_init(&pubkey);
+        if (err < 0)
+         {
+            addf (str, "error: gnutls_pubkey_init: %s\n", gnutls_strerror (err));
+            return;
+          }
+
+        err = gnutls_pubkey_import_x509(pubkey, cert, 0);
+        if (err < 0)
+          {
+            addf (str, "error: gnutls_pubkey_import_x509: %s\n", gnutls_strerror (err));
+            return;
+          }
+
+        switch (pk)
           {
           case GNUTLS_PK_RSA:
             {
               gnutls_datum_t m, e;
 
-              err = gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e);
+              err = gnutls_pubkey_get_pk_rsa_raw (pubkey, &m, &e);
               if (err < 0)
                 addf (str, "error: get_pk_rsa_raw: %s\n",
                       gnutls_strerror (err));
@@ -1189,11 +1205,34 @@ print_cert (gnutls_buffer_st * str, gnutls_x509_crt_t cert, int notsigned)
             }
             break;
 
+          case GNUTLS_PK_ECC:
+            {
+              gnutls_datum_t x, y;
+              gnutls_ecc_curve_t curve;
+
+              err = gnutls_pubkey_get_pk_ecc_raw (pubkey, &curve, &x, &y);
+              if (err < 0)
+                addf (str, "error: get_pk_ecc_raw: %s\n",
+                      gnutls_strerror (err));
+              else
+                {
+                  addf (str, _("\t\tCurve:\t%s\n"), gnutls_ecc_curve_get_name(curve));
+                  addf (str, _("\t\tX:\n"));
+                  hexdump (str, x.data, x.size, "\t\t\t");
+                  adds (str, _("\t\tY:\n"));
+                  hexdump (str, y.data, y.size, "\t\t\t");
+
+                  gnutls_free (x.data);
+                  gnutls_free (y.data);
+
+                }
+            }
+            break;
           case GNUTLS_PK_DSA:
             {
               gnutls_datum_t p, q, g, y;
 
-              err = gnutls_x509_crt_get_pk_dsa_raw (cert, &p, &q, &g, &y);
+              err = gnutls_pubkey_get_pk_dsa_raw (pubkey, &p, &q, &g, &y);
               if (err < 0)
                 addf (str, "error: get_pk_dsa_raw: %s\n",
                       gnutls_strerror (err));
@@ -1220,6 +1259,8 @@ print_cert (gnutls_buffer_st * str, gnutls_x509_crt_t cert, int notsigned)
           default:
             break;
           }
+        
+        gnutls_pubkey_deinit(pubkey);
 #endif
       }
   }