]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added initial support for certificate requests handling of X.509 extensions.
authorNikos Mavrogiannopoulos <nmav@crystal.(none)>
Sat, 4 Oct 2008 06:27:41 +0000 (09:27 +0300)
committerNikos Mavrogiannopoulos <nmav@crystal.(none)>
Sat, 4 Oct 2008 06:27:41 +0000 (09:27 +0300)
Added support to certtool to handle these extensions (add/read)

15 files changed:
includes/gnutls/x509.h
lib/x509/crl.c
lib/x509/crq.c
lib/x509/extensions.c
lib/x509/mpi.c
lib/x509/output.c
lib/x509/x509.c
lib/x509/x509_int.h
src/certtool-cfg.c
src/certtool-cfg.h
src/certtool-common.h [new file with mode: 0644]
src/certtool-gaa.c
src/certtool-gaa.h
src/certtool.c
src/certtool.gaa

index 1d512fda9a5185875ea8cc3f66052f909f1da233..ee6e937cb44fc41184ddc447bda3097fc016de85 100644 (file)
@@ -651,6 +651,11 @@ extern "C"
   struct gnutls_x509_crq_int;
   typedef struct gnutls_x509_crq_int *gnutls_x509_crq_t;
 
+  int gnutls_x509_crq_print (gnutls_x509_crq_t crq,
+                      gnutls_certificate_print_formats_t format,
+                      gnutls_datum_t * out);
+
+
   int gnutls_x509_crq_init (gnutls_x509_crq_t * crq);
   void gnutls_x509_crq_deinit (gnutls_x509_crq_t crq);
   int gnutls_x509_crq_import (gnutls_x509_crq_t crq,
@@ -703,7 +708,50 @@ extern "C"
   int gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq, 
                                    const gnutls_datum_t * m,
                                    const gnutls_datum_t * e);
+  int gnutls_x509_crq_set_subject_alt_name (gnutls_x509_crq_t crq,
+                                     gnutls_x509_subject_alt_name_t type,
+                                     const void *data,
+                                     unsigned int data_size,
+                                     unsigned int flags);
 
+  int gnutls_x509_crq_set_key_usage (gnutls_x509_crq_t crq, unsigned int usage);
+  int gnutls_x509_crq_set_basic_constraints (gnutls_x509_crq_t crq,
+                                      unsigned int ca, int pathLenConstraint);
+
+  int gnutls_x509_crq_get_extension_data (gnutls_x509_crq_t cert, int indx,
+                                   void *data, size_t * sizeof_data);
+  int gnutls_x509_crq_get_extension_info (gnutls_x509_crq_t cert, int indx,
+                                   void *oid, size_t * sizeof_oid,
+                                   int *critical);
+  int gnutls_x509_crq_get_attribute_data (gnutls_x509_crq_t cert, int indx,
+                                   void *data, size_t * sizeof_data);
+  int gnutls_x509_crq_get_attribute_info (gnutls_x509_crq_t cert, int indx,
+                                   void *oid, size_t * sizeof_oid);
+  int gnutls_x509_crq_get_pk_algorithm (gnutls_x509_crq_t crq, unsigned int *bits);
+
+  int gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq, 
+                                   gnutls_datum_t * m,
+                                   gnutls_datum_t * e);
+
+  int gnutls_x509_crq_get_key_usage (gnutls_x509_crq_t cert,
+                              unsigned int *key_usage,
+                              unsigned int *critical);
+  int gnutls_x509_crq_get_basic_constraints (gnutls_x509_crq_t cert,
+                                      unsigned int *critical,
+                                      int *ca, int *pathlen);
+  int gnutls_x509_crq_get_subject_alt_name (gnutls_x509_crq_t cert,
+                                      unsigned int seq, void *ret,
+                                      size_t * ret_size,
+                                      unsigned int *ret_type,
+                                      unsigned int *critical);
+  int gnutls_x509_crq_get_subject_alt_othername_oid (gnutls_x509_crq_t cert,
+                                              unsigned int seq,
+                                              void *ret, size_t * ret_size);
+
+  int gnutls_x509_crq_get_extension_by_oid (gnutls_x509_crq_t cert,
+                                     const char *oid, int indx,
+                                     void *buf, size_t * sizeof_buf,
+                                     unsigned int *critical);
 
 #ifdef __cplusplus
 }
index 90658a87d9a5b7772e784fd4ba9cca4190a96fcc..11f4b18febc34e209d525a27b5ed0e43c171ecd0 100644 (file)
@@ -937,7 +937,7 @@ gnutls_x509_crl_get_extension_info (gnutls_x509_crl_t crl, int indx,
 
   if (result == ASN1_ELEMENT_NOT_FOUND)
     return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
-  else if (result < 0)
+  else if (result != ASN1_SUCCESS)
     {
       gnutls_assert ();
       return _gnutls_asn2err (result);
@@ -947,7 +947,7 @@ gnutls_x509_crl_get_extension_info (gnutls_x509_crl_t crl, int indx,
            indx + 1);
   len = sizeof (str_critical);
   result = asn1_read_value (crl->crl, name, str_critical, &len);
-  if (result < 0)
+  if (result != ASN1_SUCCESS)
     {
       gnutls_assert ();
       return _gnutls_asn2err (result);
index fc02c2f575261114746cb897130b0b3c716e1f63..29ae0299a74665b705bda6b32ff58ee6fd9306b1 100644 (file)
@@ -445,6 +445,167 @@ gnutls_x509_crq_get_challenge_password (gnutls_x509_crq_t crq,
                          "1.2.840.113549.1.9.7", 0, 0, pass, sizeof_pass);
 }
 
+/* This function will attempt to set the requested attribute in
+ * the given X509v3 certificate. 
+ *
+ * Critical will be either 0 or 1.
+ */
+static int
+add_attribute (ASN1_TYPE asn, const char* root, const char *attribute_id,
+              const gnutls_datum_t * ext_data)
+{
+  int result;
+  const char *str;
+  char name[MAX_NAME_SIZE];
+
+  snprintf (name, sizeof (name), "%s", root);
+
+  /* Add a new attribute in the list.
+   */
+  result = asn1_write_value (asn, name, "NEW", 1);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  snprintf (name, sizeof (name), "%s.?LAST.type", root);
+
+  result =
+    asn1_write_value (asn, name, attribute_id, 1);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  snprintf (name, sizeof (name), "%s.?LAST.values", root);
+
+  result = asn1_write_value (asn, name, "NEW", 1);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  snprintf (name, sizeof (name), "%s.?LAST.values.?LAST", root);
+
+  result =
+    _gnutls_x509_write_value (asn, name, ext_data, 0);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  return 0;
+}
+
+/* Overwrite the given attribute (using the index)
+ * index here starts from one.
+ */
+static int
+overwrite_attribute (ASN1_TYPE asn, const char* root, unsigned int indx,
+                    const gnutls_datum_t * ext_data)
+{
+  char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
+  const char *str;
+  int result;
+
+  snprintf (name, sizeof (name), "%s.?%u", root, indx);
+
+  _gnutls_str_cpy (name2, sizeof (name2), name);
+  _gnutls_str_cat (name2, sizeof (name2), ".values.?LAST");
+
+  result = _gnutls_x509_write_value (asn, name2, ext_data, 0);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  return 0;
+}
+
+static int
+set_attribute (ASN1_TYPE asn, const char* root,
+                               const char *ext_id,
+                               const gnutls_datum_t * ext_data)
+{
+  int result;
+  int k, len;
+  char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
+  char extnID[128];
+
+  /* Find the index of the given attribute.
+   */
+  k = 0;
+  do
+    {
+      k++;
+
+      snprintf (name, sizeof (name), "%s.?%u", root, k);
+
+      len = sizeof (extnID) - 1;
+      result = asn1_read_value (asn, name, extnID, &len);
+
+      /* move to next
+       */
+
+      if (result == ASN1_ELEMENT_NOT_FOUND)
+       {
+         break;
+       }
+
+      do
+       {
+
+         _gnutls_str_cpy (name2, sizeof (name2), name);
+         _gnutls_str_cat (name2, sizeof (name2), ".type");
+
+         len = sizeof (extnID) - 1;
+         result = asn1_read_value (asn, name2, extnID, &len);
+
+         if (result == ASN1_ELEMENT_NOT_FOUND)
+           {
+             gnutls_assert ();
+             break;
+           }
+         else if (result != ASN1_SUCCESS)
+           {
+             gnutls_assert ();
+             return _gnutls_asn2err (result);
+           }
+
+         /* Handle Extension 
+          */
+         if (strcmp (extnID, ext_id) == 0)
+           {
+             /* attribute was found 
+              */
+             return overwrite_attribute (asn, root, k, ext_data);
+           }
+
+
+       }
+      while (0);
+    }
+  while (1);
+
+  if (result == ASN1_ELEMENT_NOT_FOUND)
+    {
+      return add_attribute (asn, root, ext_id, ext_data);
+    }
+  else
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+
+  return 0;
+}
+
 /**
   * gnutls_x509_crq_set_attribute_by_oid - This function will set an attribute in the request
   * @crq: should contain a gnutls_x509_crq_t structure
@@ -465,6 +626,7 @@ gnutls_x509_crq_set_attribute_by_oid (gnutls_x509_crq_t crq,
                                      size_t sizeof_buf)
 {
   int result;
+  gnutls_datum data = {buf, sizeof_buf};
 
   if (crq == NULL)
     {
@@ -472,30 +634,8 @@ gnutls_x509_crq_set_attribute_by_oid (gnutls_x509_crq_t crq,
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  /* Add the attribute.
-   */
-  result =
-    asn1_write_value (crq->crq, "certificationRequestInfo.attributes",
-                     "NEW", 1);
-  if (result != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      return _gnutls_asn2err (result);
-    }
-
-  result =
-    _gnutls_x509_encode_and_write_attribute (oid,
-                                            crq->crq,
-                                            "certificationRequestInfo.attributes.?LAST",
-                                            buf, sizeof_buf, 1);
-
-  if (result < 0)
-    {
-      gnutls_assert ();
-      return result;
-    }
-
-  return 0;
+  return set_attribute (crq->crq, "certificationRequestInfo.attributes",
+                               oid, &data);
 }
 
 /**
@@ -677,6 +817,72 @@ gnutls_x509_crq_set_key (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
   return 0;
 }
 
+/**
+  * gnutls_x509_crq_get_key_rsa_raw - This function will export the RSA public key
+  * @crq: Holds the certificate
+  * @m: will hold the modulus
+  * @e: will hold the public exponent
+  *
+  * This function will export the RSA public key's parameters found in
+  * the given structure.  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_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;
+
+  if (crq == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  ret = gnutls_x509_crq_get_pk_algorithm (crq, NULL);
+  if (ret != GNUTLS_PK_RSA)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  ret = _gnutls_x509_crq_get_mpis (crq, params, &params_size);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = _gnutls_mpi_dprint (params[0], m);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  ret = _gnutls_mpi_dprint (params[1], e);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      _gnutls_free_datum (m);
+      goto cleanup;
+    }
+
+  ret = 0;
+
+cleanup:
+  for (i = 0; i < params_size; i++)
+    {
+      _gnutls_mpi_release (&params[i]);
+    }
+  return ret;
+}
+
 /**
  * gnutls_x509_crq_set_key_rsa_raw - associate Certificate request with a key
  * @crq: should contain a #gnutls_x509_crq_t structure
@@ -972,4 +1178,789 @@ gnutls_x509_crq_get_pk_algorithm (gnutls_x509_crq_t crq, unsigned int *bits)
   return result;
 }
 
+/**
+ * gnutls_x509_crq_get_attribute_info - Get attribute id
+ * @cert: should contain a #gnutls_x509_crq_t structure
+ * @indx: Specifies which attribute OID to send. Use zero to get the first one.
+ * @oid: a pointer to a structure to hold the OID
+ * @sizeof_oid: initially holds the maximum size of @oid, on return
+ *   holds actual size of @oid.
+ *
+ * This function will return the requested attribute OID in the
+ * certificate, and the critical flag for it.  The attribute OID will
+ * be stored as a string in the provided buffer.  Use
+ * gnutls_x509_crq_get_attribute_data() to extract the data.
+ *
+ * If the buffer provided is not long enough to hold the output, then
+ * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
+ * returned.
+ *
+ * Return 0 on success.  A negative value may be returned in case of
+ * parsing error.  If you have reached the last attribute available
+ * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
+ *
+ **/
+int
+gnutls_x509_crq_get_attribute_info (gnutls_x509_crq_t cert, int indx,
+                                   void *oid, size_t * sizeof_oid)
+{
+  int result;
+  char str_critical[10];
+  char name[MAX_NAME_SIZE];
+  int len;
+
+  if (!cert)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  snprintf (name, sizeof (name), "certificationRequestInfo.attributes.?%u.type",
+           indx + 1);
+
+  len = *sizeof_oid;
+  result = asn1_read_value (cert->crq, name, oid, &len);
+  *sizeof_oid = len;
+
+  if (result == ASN1_ELEMENT_NOT_FOUND)
+    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+  else if (result < 0)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  return 0;
+
+}
+
+/**
+ * gnutls_x509_crq_get_attribute_data - Get the specified attribute data
+ * @cert: should contain a #gnutls_x509_crq_t structure
+ * @indx: Specifies which attribute OID to send. Use zero to get the first one.
+ * @data: a pointer to a structure to hold the data (may be null)
+ * @sizeof_data: initially holds the size of @oid
+ *
+ * This function will return the requested attribute data in the
+ * certificate request.  The attribute data will be stored as a string in the
+ * provided buffer.
+ *
+ * Use gnutls_x509_crq_get_attribute_info() to extract the OID.
+ * Use gnutls_x509_crq_get_attribute_by_oid() instead,
+ * if you want to get data indexed by the attribute OID rather than
+ * sequence.
+ *
+ * Return 0 on success.  A negative value may be returned in case of
+ * parsing error.  If you have reached the last attribute available
+ * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
+ **/
+int
+gnutls_x509_crq_get_attribute_data (gnutls_x509_crq_t cert, int indx,
+                                   void *data, size_t * sizeof_data)
+{
+  int result, len;
+  char name[MAX_NAME_SIZE];
+
+  if (!cert)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  snprintf (name, sizeof (name), "certificationRequestInfo.attributes.?%u.values.?1",
+           indx + 1);
+
+  len = *sizeof_data;
+  result = asn1_read_value (cert->crq, name, data, &len);
+  *sizeof_data = len;
+
+  if (result == ASN1_ELEMENT_NOT_FOUND)
+    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+  else if (result < 0)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  return 0;
+}
+
+/**
+ * gnutls_x509_crq_get_extension_info - Get extension id and criticality
+ * @cert: should contain a #gnutls_x509_crq_t structure
+ * @indx: Specifies which extension OID to send. Use zero to get the first one.
+ * @oid: a pointer to a structure to hold the OID
+ * @sizeof_oid: initially holds the maximum size of @oid, on return
+ *   holds actual size of @oid.
+ * @critical: output variable with critical flag, may be NULL.
+ *
+ * This function will return the requested extension OID in the
+ * certificate, and the critical flag for it.  The extension OID will
+ * be stored as a string in the provided buffer.  Use
+ * gnutls_x509_crq_get_extension_data() to extract the data.
+ *
+ * If the buffer provided is not long enough to hold the output, then
+ * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
+ * returned.
+ *
+ * Return 0 on success.  A negative value may be returned in case of
+ * parsing error.  If you have reached the last extension available
+ * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
+ *
+ **/
+int
+gnutls_x509_crq_get_extension_info (gnutls_x509_crq_t cert, int indx,
+                                   void *oid, size_t * sizeof_oid,
+                                   int *critical)
+{
+  int result;
+  char str_critical[10];
+  char name[MAX_NAME_SIZE];
+  unsigned char extensions[4*1024];
+  size_t extensions_size = sizeof(extensions);
+  ASN1_TYPE c2;
+  int len;
+
+  if (!cert)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  /* read extensionRequest */
+  result = gnutls_x509_crq_get_attribute_by_oid (cert, "1.2.840.113549.1.9.14",
+                                     0, extensions, &extensions_size);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  result = asn1_create_element
+    (_gnutls_get_pkix (), "PKIX1.Extensions", &c2);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_der_decoding (&c2, extensions, extensions_size, NULL);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&c2);
+      return _gnutls_asn2err (result);
+    }
+
+  snprintf (name, sizeof (name), "?%u.extnID", indx + 1);
+
+  len = *sizeof_oid;
+  result = asn1_read_value (c2, name, oid, &len);
+  *sizeof_oid = len;
+
+  if (result == ASN1_ELEMENT_NOT_FOUND)
+    {
+      asn1_delete_structure (&c2);
+      gnutls_assert();
+      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+    }
+  else if (result < 0)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&c2);
+      return _gnutls_asn2err (result);
+    }
+
+  snprintf (name, sizeof (name), "?%u.critical", indx + 1);
+  len = sizeof (str_critical);
+  result = asn1_read_value (c2, name, str_critical, &len);
+
+  asn1_delete_structure (&c2);
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  if (critical)
+    {
+      if (str_critical[0] == 'T')
+       *critical = 1;
+      else
+       *critical = 0;
+    }
+
+  return 0;
+
+}
+
+/**
+ * gnutls_x509_crq_get_extension_data - Get the specified extension data
+ * @cert: should contain a #gnutls_x509_crq_t structure
+ * @indx: Specifies which extension OID to send. Use zero to get the first one.
+ * @data: a pointer to a structure to hold the data (may be null)
+ * @sizeof_data: initially holds the size of @oid
+ *
+ * This function will return the requested extension data in the
+ * certificate.  The extension data will be stored as a string in the
+ * provided buffer.
+ *
+ * Use gnutls_x509_crq_get_extension_info() to extract the OID and
+ * critical flag.  Use gnutls_x509_crq_get_extension_by_oid() instead,
+ * if you want to get data indexed by the extension OID rather than
+ * sequence.
+ *
+ * Return 0 on success.  A negative value may be returned in case of
+ * parsing error.  If you have reached the last extension available
+ * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
+ **/
+int
+gnutls_x509_crq_get_extension_data (gnutls_x509_crq_t cert, int indx,
+                                   void *data, size_t * sizeof_data)
+{
+  int result, len;
+  char name[MAX_NAME_SIZE];
+  unsigned char extensions[4*1024];
+  size_t extensions_size = sizeof(extensions);
+  ASN1_TYPE c2;
+
+  if (!cert)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  /* read extensionRequest */
+  result = gnutls_x509_crq_get_attribute_by_oid (cert, "1.2.840.113549.1.9.14",
+                                     0, extensions, &extensions_size);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  result = asn1_create_element
+    (_gnutls_get_pkix (), "PKIX1.Extensions", &c2);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_der_decoding (&c2, extensions, extensions_size, NULL);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&c2);
+      return _gnutls_asn2err (result);
+    }
+
+  snprintf (name, sizeof (name), "?%u.extnValue",
+           indx + 1);
+
+  len = *sizeof_data;
+  result = asn1_read_value (c2, name, data, &len);
+  *sizeof_data = len;
+
+  asn1_delete_structure (&c2);
+
+  if (result == ASN1_ELEMENT_NOT_FOUND)
+    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+  else if (result < 0)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  return 0;
+}
+
+/**
+  * gnutls_x509_crq_get_key_usage - return the certificate's key usage
+  * @cert: should contain a #gnutls_x509_crq_t structure
+  * @key_usage: where the key usage bits will be stored
+  * @critical: will be non zero if the extension is marked as critical
+  *
+  * This function will return certificate's key usage, by reading the
+  * keyUsage X.509 extension (2.5.29.15). The key usage value will
+  * ORed values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
+  * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
+  * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
+  * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
+  * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
+  *
+  * Returns: the certificate key usage, or a negative value in case of
+  * parsing error.  If the certificate does not contain the keyUsage
+  * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
+  *
+  **/
+int
+gnutls_x509_crq_get_key_usage (gnutls_x509_crq_t cert,
+                              unsigned int *key_usage,
+                              unsigned int *critical)
+{
+  int result;
+  uint16_t _usage;
+  opaque buf[256];
+  size_t buf_size = sizeof(buf);
+
+  if (cert == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  result = gnutls_x509_crq_get_extension_by_oid(cert, "2.5.29.15", 0,
+                                      buf, &buf_size, critical);
+  if (result < 0)
+    {
+      gnutls_assert();
+      return result;
+    }
+
+  result = _gnutls_x509_ext_extract_keyUsage (&_usage, buf, buf_size);
+
+  *key_usage = _usage;
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  return 0;
+}
+
+/**
+ * gnutls_x509_crq_get_basic_constraints - This function returns the certificate basic constraints
+ * @cert: should contain a #gnutls_x509_crq_t structure
+ * @critical: will be non zero if the extension is marked as critical
+ * @ca: pointer to output integer indicating CA status, may be NULL,
+ *   value is 1 if the certificate CA flag is set, 0 otherwise.
+ * @pathlen: pointer to output integer indicating path length (may be
+ *   NULL), non-negative values indicate a present pathLenConstraint
+ *   field and the actual value, -1 indicate that the field is absent.
+ *
+ * This function will read the certificate's basic constraints, and
+ * return the certificates CA status.  It reads the basicConstraints
+ * X.509 extension (2.5.29.19).
+ *
+ * Return value: If the certificate is a CA a positive value will be
+ * returned, or zero if the certificate does not have CA flag set.  A
+ * negative value may be returned in case of errors.  If the
+ * certificate does not contain the basicConstraints extension
+ * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
+ **/
+int
+gnutls_x509_crq_get_basic_constraints (gnutls_x509_crq_t cert,
+                                      unsigned int *critical,
+                                      int *ca, int *pathlen)
+{
+  int result;
+  int tmp_ca;
+  opaque buf[256];
+  size_t buf_size = sizeof(buf);
+
+  if (cert == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  result = gnutls_x509_crq_get_extension_by_oid(cert, "2.5.29.19", 0,
+                                      buf, &buf_size, critical);
+  if (result < 0)
+    {
+      gnutls_assert();
+      return result;
+    }
+
+  result =
+    _gnutls_x509_ext_extract_basicConstraints (&tmp_ca,
+                                              pathlen,
+                                              buf, buf_size);
+  if (ca)
+    *ca = tmp_ca;
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  return tmp_ca;
+}
+
+static int
+get_subject_alt_name (gnutls_x509_crq_t cert,
+                     unsigned int seq, void *ret,
+                     size_t * ret_size, unsigned int *ret_type,
+                     unsigned int *critical, int othername_oid)
+{
+  int result;
+  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
+  gnutls_x509_subject_alt_name_t type;
+  opaque dnsname[2048];
+  size_t dnsname_size = sizeof(dnsname);
+
+  if (cert == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  if (ret)
+    memset (ret, 0, *ret_size);
+  else
+    *ret_size = 0;
+
+  if ((result =
+       gnutls_x509_crq_get_extension_by_oid (cert, "2.5.29.17", 0, 
+           dnsname, &dnsname_size, critical)) < 0)
+    {
+      gnutls_assert();
+      return result;
+    }
+
+  result = asn1_create_element
+    (_gnutls_get_pkix (), "PKIX1.SubjectAltName", &c2);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_der_decoding (&c2, dnsname, dnsname_size, NULL);
+
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&c2);
+      return _gnutls_asn2err (result);
+    }
+
+  result =
+    _gnutls_parse_general_name (c2, "", seq, ret, ret_size, ret_type, othername_oid);
+
+  asn1_delete_structure (&c2);
+
+  if (result < 0)
+    {
+      return result;
+    }
+
+  type = result;
+
+  return type;
+}
+
+/**
+  * gnutls_x509_crq_get_subject_alt_name - Get certificate's alternative name, if any
+  * @cert: should contain a #gnutls_x509_crq_t structure
+  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
+  * @ret: is the place where the alternative name will be copied to
+  * @ret_size: holds the size of ret.
+  * @ret_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
+  * @critical: will be non zero if the extension is marked as critical (may be null)
+  *
+  * This function will return the alternative names, contained in the
+  * given certificate. It is the same as gnutls_x509_crq_get_subject_alt_name()
+  * except for the fact that it will return the type of the alternative
+  * name in @ret_type even if the function fails for some reason (i.e.
+  * the buffer provided is not enough).
+  *
+  * The return values are the same as with gnutls_x509_crq_get_subject_alt_name().
+  *
+  **/
+int
+gnutls_x509_crq_get_subject_alt_name (gnutls_x509_crq_t cert,
+                                      unsigned int seq, void *ret,
+                                      size_t * ret_size,
+                                      unsigned int *ret_type,
+                                      unsigned int *critical)
+{
+  return get_subject_alt_name (cert ,seq, ret, ret_size, ret_type, critical, 0);
+}
+
+/**
+ * gnutls_x509_crq_get_subject_alt_othername_oid - Get SAN otherName OID
+ * @cert: should contain a #gnutls_x509_crq_t structure
+ * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
+ * @ret: is the place where the otherName OID will be copied to
+ * @ret_size: holds the size of ret.
+ *
+ * This function will extract the type OID of an otherName Subject
+ * Alternative Name, contained in the given certificate, and return
+ * the type as an enumerated element.
+ *
+ * This function is only useful if
+ * gnutls_x509_crq_get_subject_alt_name() returned
+ * %GNUTLS_SAN_OTHERNAME.
+ *
+ * Returns: the alternative subject name type on success, one of the
+ * enumerated gnutls_x509_subject_alt_name_t.  For supported OIDs, it
+ * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
+ * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
+ * unknown OIDs.  It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
+ * @ret_size is not large enough to hold the value.  In that case
+ * @ret_size will be updated with the required size.  If the
+ * certificate does not have an Alternative name with the specified
+ * sequence number and with the otherName type then
+ * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
+ **/
+int
+gnutls_x509_crq_get_subject_alt_othername_oid (gnutls_x509_crq_t cert,
+                                              unsigned int seq,
+                                              void *ret, size_t * ret_size)
+{
+  return get_subject_alt_name (cert, seq, ret, ret_size, NULL, NULL, 1);
+}
+
+/**
+  * gnutls_x509_crq_get_extension_by_oid - This function returns the specified extension
+  * @cert: should contain a #gnutls_x509_crq_t structure
+  * @oid: holds an Object Identified in null terminated string
+  * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use zero to get the first one.
+  * @buf: a pointer to a structure to hold the name (may be null)
+  * @sizeof_buf: initially holds the size of @buf
+  * @critical: will be non zero if the extension is marked as critical
+  *
+  * This function will return the extension specified by the OID in the certificate.
+  * The extensions will be returned as binary data DER encoded, in the provided
+  * buffer.
+  *
+  * A negative value may be returned in case of parsing error.
+  * If the certificate does not contain the specified extension
+  * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
+  *
+  **/
+int
+gnutls_x509_crq_get_extension_by_oid (gnutls_x509_crq_t cert,
+                                     const char *oid, int indx,
+                                     void *buf, size_t * sizeof_buf,
+                                     unsigned int *critical)
+{
+  int result;
+  gnutls_datum_t output;
+  unsigned int i;
+  char _oid[256];
+  size_t oid_size;
+
+  for (i=0;;i++)
+    {
+      oid_size = sizeof(_oid);
+      result = gnutls_x509_crq_get_extension_info ( cert, i, _oid, &oid_size, critical);
+      if (result < 0)
+        {
+          gnutls_assert();
+          return result;
+        }
+      
+      if (strcmp( oid, _oid)==0) 
+        { /* found */
+          if (indx == 0)
+            return gnutls_x509_crq_get_extension_data (cert, i, buf, sizeof_buf);
+          else indx--;
+        }
+    }
+      
+      
+  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+
+}
+
+/**
+ * gnutls_x509_crq_set_subject_alt_name - Set the subject Alternative Name
+ * @crq: a certificate of type #gnutls_x509_crq_t
+ * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
+ * @data: The data to be set
+ * @data_size: The size of data to be set
+ * @flags: GNUTLS_FSAN_SET to clear previous data or GNUTLS_FSAN_APPEND to append. 
+ *
+ * This function will set the subject alternative name certificate
+ * extension. It can set the following types:
+ *
+ * &GNUTLS_SAN_DNSNAME: as a text string
+ *
+ * &GNUTLS_SAN_RFC822NAME: as a text string
+ *
+ * &GNUTLS_SAN_URI: as a text string
+ *
+ * &GNUTLS_SAN_IPADDRESS: as a binary IP address (4 or 16 bytes)
+ * 
+ * Other values can be set as binary values with the proper DER encoding.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ *
+ * Since: 2.6.0
+ **/
+int
+gnutls_x509_crq_set_subject_alt_name (gnutls_x509_crq_t crq,
+                                     gnutls_x509_subject_alt_name_t type,
+                                     const void *data,
+                                     unsigned int data_size,
+                                     unsigned int flags)
+{
+  int result = 0;
+  opaque tmp[4*1024];
+  size_t tmp_size;
+  gnutls_datum_t der_data = { NULL, 0 };
+  gnutls_datum_t prev_der_data;
+  unsigned int critical = 0;
+
+  if (crq == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  /* Check if the extension already exists.
+   */
+
+  if (flags == GNUTLS_FSAN_APPEND)
+    {
+      tmp_size = sizeof(tmp);
+      result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
+                                              tmp, &tmp_size, &critical);
+      if (result < 0 && result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+       {
+         gnutls_assert ();
+         return result;
+       }
+    }
+
+  /* generate the extension.
+   */
+  if (result < 0)
+    {
+      prev_der_data.data = NULL;
+      prev_der_data.size = 0;
+    }
+  else
+    {
+      prev_der_data.data = tmp;
+      prev_der_data.size = tmp_size;
+    }
+
+  result = _gnutls_x509_ext_gen_subject_alt_name (type, data, data_size,
+                                                 &prev_der_data, &der_data);
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto finish;
+    }
+
+  result = _gnutls_x509_crq_set_extension (crq, "2.5.29.17", &der_data,
+                                          critical);
+
+  _gnutls_free_datum (&der_data);
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  return 0;
+
+finish:
+  return result;
+}
+
+/**
+ * gnutls_x509_crq_set_basic_constraints - Set the basicConstraints extension
+ * @crq: a certificate of type #gnutls_x509_crq_t
+ * @ca: true(1) or false(0). Depending on the Certificate authority status.
+ * @pathLenConstraint: non-negative values indicate maximum length of path,
+ *   and negative values indicate that the pathLenConstraints field should
+ *   not be present.
+ *
+ * This function will set the basicConstraints certificate extension.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_x509_crq_set_basic_constraints (gnutls_x509_crq_t crq,
+                                      unsigned int ca, int pathLenConstraint)
+{
+  int result;
+  gnutls_datum_t der_data;
+
+  if (crq == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  /* generate the extension.
+   */
+  result = _gnutls_x509_ext_gen_basicConstraints (ca, pathLenConstraint,
+                                                 &der_data);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  result = _gnutls_x509_crq_set_extension (crq, "2.5.29.19", &der_data, 1);
+
+  _gnutls_free_datum (&der_data);
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  return 0;
+}
+
+/**
+ * gnutls_x509_crq_set_key_usage - Set the keyUsage extension
+ * @crq: a certificate of type #gnutls_x509_crq_t
+ * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
+ *
+ * This function will set the keyUsage certificate extension.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_x509_crq_set_key_usage (gnutls_x509_crq_t crq, unsigned int usage)
+{
+  int result;
+  gnutls_datum_t der_data;
+
+  if (crq == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  /* generate the extension.
+   */
+  result = _gnutls_x509_ext_gen_keyUsage ((uint16_t) usage, &der_data);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  result = _gnutls_x509_crq_set_extension (crq, "2.5.29.15", &der_data, 1);
+
+  _gnutls_free_datum (&der_data);
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  return 0;
+}
+
 #endif /* ENABLE_PKI */
index a39288773707e98fd56d3868e246391aaaf83214..f84392a9c87e7912f38abd83afe1ab0d97a1569b 100644 (file)
@@ -300,7 +300,7 @@ _gnutls_x509_crl_get_extension_oid (gnutls_x509_crl_t crl,
  * Critical will be either 0 or 1.
  */
 static int
-set_extension (ASN1_TYPE asn, const char* root, const char *extension_id,
+add_extension (ASN1_TYPE asn, const char* root, const char *extension_id,
               const gnutls_datum_t * ext_data, unsigned int critical)
 {
   int result;
@@ -318,7 +318,10 @@ set_extension (ASN1_TYPE asn, const char* root, const char *extension_id,
       return _gnutls_asn2err (result);
     }
 
-  snprintf (name, sizeof (name), "%s.?LAST.extnID", root);
+  if (root[0] != 0)
+    snprintf (name, sizeof (name), "%s.?LAST.extnID", root);
+  else
+    snprintf (name, sizeof (name), "?LAST.extnID");
 
   result =
     asn1_write_value (asn, name, extension_id, 1);
@@ -333,7 +336,10 @@ set_extension (ASN1_TYPE asn, const char* root, const char *extension_id,
   else
     str = "TRUE";
 
-  snprintf (name, sizeof (name), "%s.?LAST.critical", root);
+  if (root[0] != 0)
+    snprintf (name, sizeof (name), "%s.?LAST.critical", root);
+  else
+    snprintf (name, sizeof (name), "?LAST.critical");
 
   result =
     asn1_write_value (asn, name, str, 1);
@@ -343,7 +349,10 @@ set_extension (ASN1_TYPE asn, const char* root, const char *extension_id,
       return _gnutls_asn2err (result);
     }
 
-  snprintf (name, sizeof (name), "%s.?LAST.extnValue", root);
+  if (root[0] != 0)
+    snprintf (name, sizeof (name), "%s.?LAST.extnValue", root);
+  else
+    snprintf (name, sizeof (name), "?LAST.extnValue");
 
   result =
     _gnutls_x509_write_value (asn, name, ext_data, 0);
@@ -367,7 +376,10 @@ overwrite_extension (ASN1_TYPE asn, const char* root, unsigned int indx,
   const char *str;
   int result;
 
-  snprintf (name, sizeof (name), "%s.?%u", root, indx);
+  if (root[0] != 0)
+    snprintf (name, sizeof (name), "%s.?%u", root, indx);
+  else
+    snprintf (name, sizeof (name), "?%u", indx);
 
   if (critical == 0)
     str = "FALSE";
@@ -397,13 +409,8 @@ overwrite_extension (ASN1_TYPE asn, const char* root, unsigned int indx,
   return 0;
 }
 
-/* This function will attempt to overwrite the requested extension with
- * the given one. 
- *
- * Critical will be either 0 or 1.
- */
-int
-_gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
+static int
+set_extension (ASN1_TYPE asn, const char* root,
                                const char *ext_id,
                                const gnutls_datum_t * ext_data,
                                unsigned int critical)
@@ -420,10 +427,13 @@ _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
     {
       k++;
 
-      snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", k);
+      if (root[0] != 0)
+        snprintf (name, sizeof (name), "%s.?%u", root, k);
+      else
+        snprintf (name, sizeof (name), "?%u", k);
 
       len = sizeof (extnID) - 1;
-      result = asn1_read_value (cert->cert, name, extnID, &len);
+      result = asn1_read_value (asn, name, extnID, &len);
 
       /* move to next
        */
@@ -440,7 +450,7 @@ _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
          _gnutls_str_cat (name2, sizeof (name2), ".extnID");
 
          len = sizeof (extnID) - 1;
-         result = asn1_read_value (cert->cert, name2, extnID, &len);
+         result = asn1_read_value (asn, name2, extnID, &len);
 
          if (result == ASN1_ELEMENT_NOT_FOUND)
            {
@@ -459,7 +469,7 @@ _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
            {
              /* extension was found 
               */
-             return overwrite_extension (cert->cert, "tbsCertificate.extensions", k, ext_data, critical);
+             return overwrite_extension (asn, root, k, ext_data, critical);
            }
 
 
@@ -470,7 +480,7 @@ _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
 
   if (result == ASN1_ELEMENT_NOT_FOUND)
     {
-      return set_extension (cert->cert, "tbsCertificate.extensions", ext_id, ext_data, critical);
+      return add_extension (asn, root, ext_id, ext_data, critical);
     }
   else
     {
@@ -482,86 +492,110 @@ _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
   return 0;
 }
 
+/* This function will attempt to overwrite the requested extension with
+ * the given one. 
+ *
+ * Critical will be either 0 or 1.
+ */
+int
+_gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
+                               const char *ext_id,
+                               const gnutls_datum_t * ext_data,
+                               unsigned int critical)
+{
+  return set_extension( cert->cert, "tbsCertificate.extensions", ext_id, ext_data, critical); 
+}
+
 int
 _gnutls_x509_crl_set_extension (gnutls_x509_crl_t crl,
                                const char *ext_id,
                                const gnutls_datum_t * ext_data,
                                unsigned int critical)
 {
+  return set_extension( crl->crl, "tbsCertList.crlExtensions", ext_id, ext_data, critical); 
+}
+
+#ifdef ENABLE_PKI
+int
+_gnutls_x509_crq_set_extension (gnutls_x509_crq_t crq,
+                               const char *ext_id,
+                               const gnutls_datum_t * ext_data,
+                               unsigned int critical)
+{
+  unsigned char extensions[4*1024];
+  size_t extensions_size = sizeof(extensions);
+  gnutls_datum der;
+  ASN1_TYPE c2;
   int result;
-  int k, len;
-  char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
-  char extnID[128];
 
-  /* Find the index of the given extension.
-   */
-  k = 0;
-  do
+  result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
+                                     0, extensions, &extensions_size);
+  if (result < 0)
     {
-      k++;
-
-      snprintf (name, sizeof (name), "tbsCertList.crlExtensions.?%u", k);
-
-      len = sizeof (extnID) - 1;
-      result = asn1_read_value (crl->crl, name, extnID, &len);
-
-      /* move to next
-       */
-
-      if (result == ASN1_ELEMENT_NOT_FOUND)
-       {
-         break;
-       }
-
-      do
-       {
-
-         _gnutls_str_cpy (name2, sizeof (name2), name);
-         _gnutls_str_cat (name2, sizeof (name2), ".extnID");
+      if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) 
+        {
+          extensions_size = 0;
+        } 
+      else 
+        {
+          gnutls_assert ();
+          return result;
+        }
+    }
 
-         len = sizeof (extnID) - 1;
-         result = asn1_read_value (crl->crl, name2, extnID, &len);
+  result = asn1_create_element
+    (_gnutls_get_pkix (), "PKIX1.Extensions", &c2);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
 
-         if (result == ASN1_ELEMENT_NOT_FOUND)
-           {
-             gnutls_assert ();
-             break;
-           }
-         else if (result != ASN1_SUCCESS)
-           {
-             gnutls_assert ();
-             return _gnutls_asn2err (result);
-           }
+  if (extensions_size > 0)
+    {
+      result = asn1_der_decoding (&c2, extensions, extensions_size, NULL);
+      if (result != ASN1_SUCCESS)
+        {
+          gnutls_assert ();
+          asn1_delete_structure (&c2);
+          return _gnutls_asn2err (result);
+        }
+    }
 
-         /* Handle Extension 
-          */
-         if (strcmp (extnID, ext_id) == 0)
-           {
-             /* extension was found 
-              */
-             return overwrite_extension (crl->crl, "tbsCertList.crlExtensions", k, ext_data, critical);
-           }
+  result = set_extension( c2, "", ext_id, ext_data, critical); 
+  if (result < 0)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&c2);
+      return result;
+    }
 
+  result = _gnutls_x509_der_encode (c2, "", &der, 0);
 
-       }
-      while (0);
-    }
-  while (1);
+  asn1_delete_structure (&c2);
 
-  if (result == ASN1_ELEMENT_NOT_FOUND)
+  if (result < 0)
     {
-      return set_extension (crl->crl, "tbsCertList.crlExtensions", ext_id, ext_data, critical);
+      gnutls_assert ();
+      return result;
     }
-  else
+
+  result = gnutls_x509_crq_set_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
+                                     der.data, der.size);
+                                     
+  _gnutls_free_datum( &der);
+
+  if (result < 0)
     {
       gnutls_assert ();
-      return _gnutls_asn2err (result);
+      return result;
     }
 
-
+  
   return 0;
 }
 
+#endif
 
 /* Here we only extract the KeyUsage field, from the DER encoded
  * extension.
index 9ae61ee70ef58ddf746528ceb2370bbe37e52504..8af3af07bcaa07764d812c132bb475cd7a888228 100644 (file)
@@ -205,27 +205,23 @@ _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, bigint_t * params)
 
 /* Extracts DSA and RSA parameters from a certificate.
  */
-int
-_gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
+static int
+ get_mpis (int pk_algorithm, ASN1_TYPE asn, const char* root,
                           bigint_t * params, int *params_size)
 {
   int result;
-  int pk_algorithm;
+  char name[256];
   gnutls_datum tmp = { NULL, 0 };
 
-  /* Read the algorithm's OID
-   */
-  pk_algorithm = gnutls_x509_crt_get_pk_algorithm (cert, NULL);
-
   /* Read the algorithm's parameters
    */
-  result = _gnutls_x509_read_value (cert->cert,
-                                   "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
-                                   &tmp, 2);
+  snprintf(name, sizeof(name), "%s.subjectPublicKey", root);
+  result = _gnutls_x509_read_value (asn, name, &tmp, 2);
 
   if (result < 0)
     {
       gnutls_assert ();
+      fprintf(stderr, "name: %s\n", name);
       return result;
     }
 
@@ -278,9 +274,8 @@ _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
        */
       _gnutls_free_datum (&tmp);
 
-      result = _gnutls_x509_read_value (cert->cert,
-                                       "tbsCertificate.subjectPublicKeyInfo.algorithm.parameters",
-                                       &tmp, 0);
+      snprintf(name, sizeof(name), "%s.algorithm.parameters", root);
+      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
@@ -319,6 +314,40 @@ error:
   return result;
 }
 
+/* Extracts DSA and RSA parameters from a certificate.
+ */
+int
+_gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
+                          bigint_t * params, int *params_size)
+{
+  int result;
+  int pk_algorithm;
+  gnutls_datum tmp = { NULL, 0 };
+
+  /* Read the algorithm's OID
+   */
+  pk_algorithm = gnutls_x509_crt_get_pk_algorithm (cert, NULL);
+  
+  return get_mpis( pk_algorithm, cert->cert, "tbsCertificate.subjectPublicKeyInfo", params, params_size);
+}
+
+/* Extracts DSA and RSA parameters from a certificate.
+ */
+int
+_gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert,
+                          bigint_t * params, int *params_size)
+{
+  int result;
+  int pk_algorithm;
+  gnutls_datum tmp = { NULL, 0 };
+
+  /* Read the algorithm's OID
+   */
+  pk_algorithm = gnutls_x509_crq_get_pk_algorithm (cert, NULL);
+  
+  return get_mpis( pk_algorithm, cert->crq, "certificationRequestInfo.subjectPKInfo", params, params_size);
+}
+
 /*
  * some x509 certificate functions that relate to MPI parameter
  * setting. This writes the BIT STRING subjectPublicKey.
index 93497d86296ab1b4ec9d2df21a35ff09bd84beeb..4451421484a846725db46f6dfbaf6120c7d5a25e 100644 (file)
@@ -209,6 +209,7 @@ print_ski (gnutls_string * str, gnutls_x509_crt_t cert)
 
 #define TYPE_CRL 1
 #define TYPE_CRT 2
+#define TYPE_CRQ 3
 
 static void
 print_aki (gnutls_string * str, int type, void* cert)
@@ -219,8 +220,12 @@ print_aki (gnutls_string * str, int type, void* cert)
 
   if (type == TYPE_CRT)
     err = gnutls_x509_crt_get_authority_key_id (cert, buffer, &size, NULL);
-  else
+  else if (type == TYPE_CRL)
     err = gnutls_x509_crl_get_authority_key_id (cert, buffer, &size, NULL);
+  else {
+    gnutls_assert();
+    return;
+  }
 
   if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
     {
@@ -255,12 +260,18 @@ print_aki (gnutls_string * str, int type, void* cert)
 }
 
 static void
-print_key_usage (gnutls_string * str, gnutls_x509_crt_t cert)
+print_key_usage (gnutls_string * str, const char* prefix, int type, void* cert)
 {
   unsigned int key_usage;
   int err;
 
-  err = gnutls_x509_crt_get_key_usage (cert, &key_usage, NULL);
+  if (type == TYPE_CRT)
+    err = gnutls_x509_crt_get_key_usage (cert, &key_usage, NULL);
+  else if (type == TYPE_CRQ)
+    err = gnutls_x509_crq_get_key_usage (cert, &key_usage, NULL);
+  else
+    return;
+
   if (err < 0)
     {
       addf (str, "error: get_key_usage: %s\n", gnutls_strerror (err));
@@ -268,23 +279,23 @@ print_key_usage (gnutls_string * str, gnutls_x509_crt_t cert)
     }
 
   if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
-    addf (str, _("\t\t\tDigital signature.\n"));
+    addf (str, _("%s\t\t\tDigital signature.\n"), prefix);
   if (key_usage & GNUTLS_KEY_NON_REPUDIATION)
-    addf (str, _("\t\t\tNon repudiation.\n"));
+    addf (str, _("%s\t\t\tNon repudiation.\n"), prefix);
   if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
-    addf (str, _("\t\t\tKey encipherment.\n"));
+    addf (str, _("%s\t\t\tKey encipherment.\n"), prefix);
   if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
-    addf (str, _("\t\t\tData encipherment.\n"));
+    addf (str, _("%s\t\t\tData encipherment.\n"), prefix);
   if (key_usage & GNUTLS_KEY_KEY_AGREEMENT)
-    addf (str, _("\t\t\tKey agreement.\n"));
+    addf (str, _("%s\t\t\tKey agreement.\n"), prefix);
   if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN)
-    addf (str, _("\t\t\tCertificate signing.\n"));
+    addf (str, _("%s\t\t\tCertificate signing.\n"), prefix);
   if (key_usage & GNUTLS_KEY_CRL_SIGN)
-    addf (str, _("\t\t\tCRL signing.\n"));
+    addf (str, _("%s\t\t\tCRL signing.\n"), prefix);
   if (key_usage & GNUTLS_KEY_ENCIPHER_ONLY)
-    addf (str, _("\t\t\tKey encipher only.\n"));
+    addf (str, _("%s\t\t\tKey encipher only.\n"), prefix);
   if (key_usage & GNUTLS_KEY_DECIPHER_ONLY)
-    addf (str, _("\t\t\tKey decipher only.\n"));
+    addf (str, _("%s\t\t\tKey decipher only.\n"), prefix);
 }
 
 #ifdef ENABLE_PKI
@@ -423,12 +434,17 @@ print_key_purpose (gnutls_string * str, gnutls_x509_crt_t cert)
 #endif
 
 static void
-print_basic (gnutls_string * str, gnutls_x509_crt_t cert)
+print_basic (gnutls_string * str, const char* prefix, int type, void* cert)
 {
   int pathlen;
   int err;
 
-  err = gnutls_x509_crt_get_basic_constraints (cert, NULL, NULL, &pathlen);
+  if (type == TYPE_CRT)
+    err = gnutls_x509_crt_get_basic_constraints (cert, NULL, NULL, &pathlen);
+  else if (type == TYPE_CRQ)
+    err = gnutls_x509_crq_get_basic_constraints (cert, NULL, NULL, &pathlen);
+  else return;
+  
   if (err < 0)
     {
       addf (str, "error: get_basic_constraints: %s\n", gnutls_strerror (err));
@@ -436,17 +452,17 @@ print_basic (gnutls_string * str, gnutls_x509_crt_t cert)
     }
 
   if (err == 0)
-    addf (str, _("\t\t\tCertificate Authority (CA): FALSE\n"));
+    addf (str, _("%s\t\t\tCertificate Authority (CA): FALSE\n"), prefix);
   else
-    addf (str, _("\t\t\tCertificate Authority (CA): TRUE\n"));
+    addf (str, _("%s\t\t\tCertificate Authority (CA): TRUE\n"), prefix);
 
   if (pathlen >= 0)
-    addf (str, _("\t\t\tPath Length Constraint: %d\n"), pathlen);
+    addf (str, _("%s\t\t\tPath Length Constraint: %d\n"), prefix, pathlen);
 }
 
 
 static void
-print_san (gnutls_string * str, gnutls_x509_crt_t cert)
+print_san (gnutls_string * str, const char* prefix, int type, void* cert)
 {
   unsigned int san_idx;
   char str_ip[64];
@@ -458,9 +474,14 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert)
       size_t size = 0;
       int err;
 
-      err =
-       gnutls_x509_crt_get_subject_alt_name (cert, san_idx, buffer, &size,
+      if (type == TYPE_CRT)
+        err = gnutls_x509_crt_get_subject_alt_name (cert, san_idx, buffer, &size,
                                              NULL);
+      else if (type == TYPE_CRQ)
+        err = gnutls_x509_crq_get_subject_alt_name (cert, san_idx, buffer, &size,
+            NULL, NULL);
+      else return;
+
       if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
        break;
       if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
@@ -477,8 +498,13 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert)
          return;
        }
 
-      err = gnutls_x509_crt_get_subject_alt_name (cert, san_idx,
-                                                 buffer, &size, NULL);
+      if (type == TYPE_CRT)
+        err = gnutls_x509_crt_get_subject_alt_name (cert, san_idx, buffer, &size,
+                                             NULL);
+      else if (type == TYPE_CRQ)
+        err = gnutls_x509_crq_get_subject_alt_name (cert, san_idx, buffer, &size,
+                                             NULL, NULL);
+
       if (err < 0)
        {
          gnutls_free (buffer);
@@ -490,23 +516,23 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert)
       switch (err)
        {
        case GNUTLS_SAN_DNSNAME:
-         addf (str, "\t\t\tDNSname: %.*s\n", size, buffer);
+         addf (str, "%s\t\t\tDNSname: %.*s\n", prefix, size, buffer);
          break;
 
        case GNUTLS_SAN_RFC822NAME:
-         addf (str, "\t\t\tRFC822name: %.*s\n", size, buffer);
+         addf (str, "%s\t\t\tRFC822name: %.*s\n", prefix, size, buffer);
          break;
 
        case GNUTLS_SAN_URI:
-         addf (str, "\t\t\tURI: %.*s\n", size, buffer);
+         addf (str, "%s\t\t\tURI: %.*s\n", prefix, size, buffer);
          break;
        case GNUTLS_SAN_IPADDRESS:
          p = ip_to_string(buffer, size, str_ip, sizeof(str_ip));
          if (p == NULL) p = ERROR_STR;
-         addf (str, "\t\t\tIPAddress: %s\n", p);
+         addf (str, "%s\t\t\tIPAddress: %s\n", prefix, p);
          break;
        case GNUTLS_SAN_DN:
-         addf (str, "\t\t\tdirectoryName: %.*s\n", size, buffer);
+         addf (str, "%s\t\t\tdirectoryName: %.*s\n", prefix, size, buffer);
          break;
 
        case GNUTLS_SAN_OTHERNAME:
@@ -515,8 +541,13 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert)
            size_t oidsize;
 
            oidsize = 0;
-           err = gnutls_x509_crt_get_subject_alt_othername_oid
+            if (type == TYPE_CRT)
+             err = gnutls_x509_crt_get_subject_alt_othername_oid
+             (cert, san_idx, oid, &oidsize);
+            else if (type == TYPE_CRQ)
+             err = gnutls_x509_crq_get_subject_alt_othername_oid
              (cert, san_idx, oid, &oidsize);
+            
            if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
              {
                gnutls_free (buffer);
@@ -533,7 +564,11 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert)
                return;
              }
 
-           err = gnutls_x509_crt_get_subject_alt_othername_oid
+            if (type == TYPE_CRT)
+             err = gnutls_x509_crt_get_subject_alt_othername_oid
+             (cert, san_idx, oid, &oidsize);
+            else if (type == TYPE_CRQ)
+             err = gnutls_x509_crq_get_subject_alt_othername_oid
              (cert, san_idx, oid, &oidsize);
            if (err < 0)
              {
@@ -545,13 +580,13 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert)
              }
 
            if (err == GNUTLS_SAN_OTHERNAME_XMPP)
-             addf (str, _("\t\t\tXMPP Address: %.*s\n"), size, buffer);
+             addf (str, _("%s\t\t\tXMPP Address: %.*s\n"), prefix, size, buffer);
            else
              {
-               addf (str, _("\t\t\totherName OID: %.*s\n"), oidsize, oid);
-               addf (str, _("\t\t\totherName DER: "));
+               addf (str, _("%s\t\t\totherName OID: %.*s\n"), prefix, oidsize, oid);
+               addf (str, _("%s\t\t\totherName DER: "), prefix);
                hexprint (str, buffer, size);
-               addf (str, _("\n\t\t\totherName ASCII: "));
+               addf (str, _("\n%s\t\t\totherName ASCII: "), prefix);
                asciiprint (str, buffer, size);
                addf (str, "\n");
              }
@@ -568,170 +603,9 @@ print_san (gnutls_string * str, gnutls_x509_crt_t cert)
     }
 }
 
-static void
-print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
+void print_extensions( gnutls_string * str, const char* prefix, int type, void* cert)
 {
-  /* Version. */
-  {
-    int version = gnutls_x509_crt_get_version (cert);
-    if (version < 0)
-      addf (str, "error: get_version: %s\n", gnutls_strerror (version));
-    else
-      addf (str, _("\tVersion: %d\n"), version);
-  }
-
-  /* Serial. */
-  {
-    char serial[128];
-    size_t serial_size = sizeof (serial);
-    int err;
-
-    err = gnutls_x509_crt_get_serial (cert, serial, &serial_size);
-    if (err < 0)
-      addf (str, "error: get_serial: %s\n", gnutls_strerror (err));
-    else
-      {
-       addf (str, _("\tSerial Number (hex): "));
-       hexprint (str, serial, serial_size);
-       addf (str, "\n");
-      }
-  }
-
-  /* Issuer. */
-  if (!notsigned)
-    {
-      char dn[1024];
-      size_t dn_size = sizeof (dn);
-      int err;
-
-      err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size);
-      if (err < 0)
-       addf (str, "error: get_issuer_dn: %s\n", gnutls_strerror (err));
-      else
-       addf (str, _("\tIssuer: %s\n"), dn);
-    }
-
-  /* Validity. */
-  {
-    time_t tim;
-
-    addf (str, _("\tValidity:\n"));
-
-    tim = gnutls_x509_crt_get_activation_time (cert);
-    {
-      char s[42];
-      size_t max = sizeof (s);
-      struct tm t;
-
-      if (gmtime_r (&tim, &t) == NULL)
-       addf (str, "error: gmtime_r (%d)\n", t);
-      else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
-       addf (str, "error: strftime (%d)\n", t);
-      else
-       addf (str, _("\t\tNot Before: %s\n"), s);
-    }
-
-    tim = gnutls_x509_crt_get_expiration_time (cert);
-    {
-      char s[42];
-      size_t max = sizeof (s);
-      struct tm t;
-
-      if (gmtime_r (&tim, &t) == NULL)
-       addf (str, "error: gmtime_r (%d)\n", t);
-      else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
-       addf (str, "error: strftime (%d)\n", t);
-      else
-       addf (str, _("\t\tNot After: %s\n"), s);
-    }
-  }
-
-  /* Subject. */
-  {
-    char dn[1024];
-    size_t dn_size = sizeof (dn);
-    int err;
-
-    err = gnutls_x509_crt_get_dn (cert, dn, &dn_size);
-    if (err < 0)
-      addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
-    else
-      addf (str, _("\tSubject: %s\n"), dn);
-  }
-
-  /* SubjectPublicKeyInfo. */
-  {
-    int err;
-    unsigned int bits;
-
-    err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
-    if (err < 0)
-      addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
-    else
-      {
-       const char *name = gnutls_pk_algorithm_get_name (err);
-       if (name == NULL)
-         name = _("unknown");
-
-       addf (str, _("\tSubject Public Key Algorithm: %s\n"), name);
-#ifdef ENABLE_PKI
-       switch (err)
-         {
-         case GNUTLS_PK_RSA:
-           {
-             gnutls_datum_t m, e;
-
-             err = gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e);
-             if (err < 0)
-               addf (str, "error: get_pk_rsa_raw: %s\n",
-                     gnutls_strerror (err));
-             else
-               {
-                 addf (str, _("\t\tModulus (bits %d):\n"), bits);
-                 hexdump (str, m.data, m.size, "\t\t\t");
-                 addf (str, _("\t\tExponent:\n"));
-                 hexdump (str, e.data, e.size, "\t\t\t");
-               }
-
-             gnutls_free (m.data);
-             gnutls_free (e.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);
-             if (err < 0)
-               addf (str, "error: get_pk_dsa_raw: %s\n",
-                     gnutls_strerror (err));
-             else
-               {
-                 addf (str, _("\t\tPublic key (bits %d):\n"), bits);
-                 hexdump (str, y.data, y.size, "\t\t\t");
-                 addf (str, _("\t\tP:\n"));
-                 hexdump (str, p.data, p.size, "\t\t\t");
-                 addf (str, _("\t\tQ:\n"));
-                 hexdump (str, q.data, q.size, "\t\t\t");
-                 addf (str, _("\t\tG:\n"));
-                 hexdump (str, g.data, g.size, "\t\t\t");
-               }
-           }
-           break;
-
-         default:
-           break;
-         }
-#endif
-      }
-  }
-
-  /* Extensions. */
-  if (gnutls_x509_crt_get_version (cert) >= 3)
-    {
-      size_t i;
-      int err = 0;
+int i, err;
 
       for (i = 0;; i++)
        {
@@ -747,9 +621,19 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
          size_t aki_idx = 0;
          size_t crldist_idx = 0;
 
-         err = gnutls_x509_crt_get_extension_info (cert, i,
+         if (type == TYPE_CRT)
+           err = gnutls_x509_crt_get_extension_info (cert, i,
                                                    oid, &sizeof_oid,
                                                    &critical);
+         else if (type == TYPE_CRQ)
+           err = gnutls_x509_crq_get_extension_info (cert, i,
+                                                   oid, &sizeof_oid,
+                                                   &critical);
+          else {
+            gnutls_assert();
+            return;
+          }
+
          if (err < 0)
            {
              if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
@@ -760,7 +644,7 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
            }
 
          if (i == 0)
-           addf (str, _("\tExtensions:\n"));
+           addf (str, _("%s\tExtensions:\n"), prefix);
 
          if (strcmp (oid, "2.5.29.19") == 0)
            {
@@ -770,10 +654,10 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
                  continue;
                }
 
-             addf (str, _("\t\tBasic Constraints (%s):\n"),
+             addf (str, _("%s\t\tBasic Constraints (%s):\n"), prefix,
                    critical ? _("critical") : _("not critical"));
 
-             print_basic (str, cert);
+             print_basic (str, prefix, type, cert);
 
              basic_idx++;
            }
@@ -785,10 +669,10 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
                  continue;
                }
 
-             addf (str, _("\t\tSubject Key Identifier (%s):\n"),
+             addf (str, _("%s\t\tSubject Key Identifier (%s):\n"), prefix,
                    critical ? _("critical") : _("not critical"));
 
-             print_ski (str, cert);
+             if (type == TYPE_CRT) print_ski (str, cert);
 
              ski_idx++;
            }
@@ -800,10 +684,10 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
                  continue;
                }
 
-             addf (str, _("\t\tAuthority Key Identifier (%s):\n"),
+             addf (str, _("%s\t\tAuthority Key Identifier (%s):\n"), prefix,
                    critical ? _("critical") : _("not critical"));
 
-             print_aki (str, TYPE_CRT, cert);
+             if (type == TYPE_CRT) print_aki (str, TYPE_CRT, cert);
 
              aki_idx++;
            }
@@ -815,10 +699,10 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
                  continue;
                }
 
-             addf (str, _("\t\tKey Usage (%s):\n"),
+             addf (str, _("%s\t\tKey Usage (%s):\n"), prefix,
                    critical ? _("critical") : _("not critical"));
 
-             print_key_usage (str, cert);
+             print_key_usage (str, prefix, type, cert);
 
              keyusage_idx++;
            }
@@ -830,11 +714,11 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
                  continue;
                }
 
-             addf (str, _("\t\tKey Purpose (%s):\n"),
+             addf (str, _("%s\t\tKey Purpose (%s):\n"), prefix,
                    critical ? _("critical") : _("not critical"));
 
 #ifdef ENABLE_PKI
-             print_key_purpose (str, cert);
+             if (type == TYPE_CRT) print_key_purpose (str, cert);
 #endif
 
              keypurpose_idx++;
@@ -847,10 +731,10 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
                  continue;
                }
 
-             addf (str, _("\t\tSubject Alternative Name (%s):\n"),
+             addf (str, _("%s\t\tSubject Alternative Name (%s):\n"), prefix,
                    critical ? _("critical") : _("not critical"));
 
-             print_san (str, cert);
+             print_san (str, prefix, type, cert);
 
              san_idx++;
            }
@@ -862,11 +746,11 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
                  continue;
                }
 
-             addf (str, _("\t\tCRL Distribution points (%s):\n"),
+             addf (str, _("%s\t\tCRL Distribution points (%s):\n"), prefix,
                    critical ? _("critical") : _("not critical"));
 
 #ifdef ENABLE_PKI
-             print_crldist (str, cert);
+             if (type == TYPE_CRT) print_crldist (str, cert);
 #endif
 
              crldist_idx++;
@@ -879,58 +763,243 @@ print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
                  continue;
                }
 
-             addf (str, _("\t\tProxy Certificate Information (%s):\n"),
+             addf (str, _("%s\t\tProxy Certificate Information (%s):\n"), prefix,
+                   critical ? _("critical") : _("not critical"));
+
+             if (type == TYPE_CRT) print_proxy (str, cert);
+
+             proxy_idx++;
+           }
+         else
+           {
+             char *buffer;
+             size_t extlen = 0;
+
+             addf (str, _("%s\t\tUnknown extension %s (%s):\n"), oid, prefix,
                    critical ? _("critical") : _("not critical"));
 
-             print_proxy (str, cert);
+             if (type == TYPE_CRT) 
+               err = gnutls_x509_crt_get_extension_data (cert, i, NULL, &extlen);
+              else if (type == TYPE_CRQ)
+               err = gnutls_x509_crq_get_extension_data (cert, i, NULL, &extlen);
+              else {
+                gnutls_assert();
+                return;
+              }
+                                                  
+             if (err < 0)
+               {
+                 addf (str, "error: get_extension_data: %s\n",
+                       gnutls_strerror (err));
+                 continue;
+               }
+
+             buffer = gnutls_malloc (extlen);
+             if (!buffer)
+               {
+                 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
+                 continue;
+               }
+
+             if (type == TYPE_CRT) 
+               err = gnutls_x509_crt_get_extension_data (cert, i, buffer, &extlen);
+              else if (type == TYPE_CRQ)
+               err = gnutls_x509_crq_get_extension_data (cert, i, buffer, &extlen);
+
+             if (err < 0)
+               {
+                 gnutls_free (buffer);
+                 addf (str, "error: get_extension_data2: %s\n",
+                       gnutls_strerror (err));
+                 continue;
+               }
+
+             addf (str, _("%s\t\t\tASCII: "), prefix);
+             asciiprint (str, buffer, extlen);
+             addf (str, "\n");
+
+             addf (str, _("%s\t\t\tHexdump: "), prefix);
+             hexprint (str, buffer, extlen);
+             adds (str, "\n");
+
+             gnutls_free (buffer);
+           }
+       }
+}
+
+static void
+print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
+{
+  /* Version. */
+  {
+    int version = gnutls_x509_crt_get_version (cert);
+    if (version < 0)
+      addf (str, "error: get_version: %s\n", gnutls_strerror (version));
+    else
+      addf (str, _("\tVersion: %d\n"), version);
+  }
+
+  /* Serial. */
+  {
+    char serial[128];
+    size_t serial_size = sizeof (serial);
+    int err;
+
+    err = gnutls_x509_crt_get_serial (cert, serial, &serial_size);
+    if (err < 0)
+      addf (str, "error: get_serial: %s\n", gnutls_strerror (err));
+    else
+      {
+       addf (str, _("\tSerial Number (hex): "));
+       hexprint (str, serial, serial_size);
+       addf (str, "\n");
+      }
+  }
+
+  /* Issuer. */
+  if (!notsigned)
+    {
+      char dn[1024];
+      size_t dn_size = sizeof (dn);
+      int err;
+
+      err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size);
+      if (err < 0)
+       addf (str, "error: get_issuer_dn: %s\n", gnutls_strerror (err));
+      else
+       addf (str, _("\tIssuer: %s\n"), dn);
+    }
+
+  /* Validity. */
+  {
+    time_t tim;
+
+    addf (str, _("\tValidity:\n"));
+
+    tim = gnutls_x509_crt_get_activation_time (cert);
+    {
+      char s[42];
+      size_t max = sizeof (s);
+      struct tm t;
+
+      if (gmtime_r (&tim, &t) == NULL)
+       addf (str, "error: gmtime_r (%d)\n", t);
+      else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
+       addf (str, "error: strftime (%d)\n", t);
+      else
+       addf (str, _("\t\tNot Before: %s\n"), s);
+    }
+
+    tim = gnutls_x509_crt_get_expiration_time (cert);
+    {
+      char s[42];
+      size_t max = sizeof (s);
+      struct tm t;
+
+      if (gmtime_r (&tim, &t) == NULL)
+       addf (str, "error: gmtime_r (%d)\n", t);
+      else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
+       addf (str, "error: strftime (%d)\n", t);
+      else
+       addf (str, _("\t\tNot After: %s\n"), s);
+    }
+  }
+
+  /* Subject. */
+  {
+    char dn[1024];
+    size_t dn_size = sizeof (dn);
+    int err;
+
+    err = gnutls_x509_crt_get_dn (cert, dn, &dn_size);
+    if (err < 0)
+      addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
+    else
+      addf (str, _("\tSubject: %s\n"), dn);
+  }
+
+  /* SubjectPublicKeyInfo. */
+  {
+    int err;
+    unsigned int bits;
+
+    err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
+    if (err < 0)
+      addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
+    else
+      {
+       const char *name = gnutls_pk_algorithm_get_name (err);
+       if (name == NULL)
+         name = _("unknown");
+
+       addf (str, _("\tSubject Public Key Algorithm: %s\n"), name);
+#ifdef ENABLE_PKI
+       switch (err)
+         {
+         case GNUTLS_PK_RSA:
+           {
+             gnutls_datum_t m, e;
+
+             err = gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e);
+             if (err < 0)
+               addf (str, "error: get_pk_rsa_raw: %s\n",
+                     gnutls_strerror (err));
+             else
+               {
+                 addf (str, _("\t\tModulus (bits %d):\n"), bits);
+                 hexdump (str, m.data, m.size, "\t\t\t");
+                 addf (str, _("\t\tExponent:\n"));
+                 hexdump (str, e.data, e.size, "\t\t\t");
+
+                 gnutls_free (m.data);
+                 gnutls_free (e.data);
+               }
 
-             proxy_idx++;
            }
-         else
-           {
-             char *buffer;
-             size_t extlen = 0;
+           break;
 
-             addf (str, _("\t\tUnknown extension %s (%s):\n"), oid,
-                   critical ? _("critical") : _("not critical"));
+         case GNUTLS_PK_DSA:
+           {
+             gnutls_datum_t p, q, g, y;
 
-             err = gnutls_x509_crt_get_extension_data (cert, i,
-                                                       NULL, &extlen);
+             err = gnutls_x509_crt_get_pk_dsa_raw (cert, &p, &q, &g, &y);
              if (err < 0)
+               addf (str, "error: get_pk_dsa_raw: %s\n",
+                     gnutls_strerror (err));
+             else
                {
-                 addf (str, "error: get_extension_data: %s\n",
-                       gnutls_strerror (err));
-                 continue;
-               }
+                 addf (str, _("\t\tPublic key (bits %d):\n"), bits);
+                 hexdump (str, y.data, y.size, "\t\t\t");
+                 addf (str, _("\t\tP:\n"));
+                 hexdump (str, p.data, p.size, "\t\t\t");
+                 addf (str, _("\t\tQ:\n"));
+                 hexdump (str, q.data, q.size, "\t\t\t");
+                 addf (str, _("\t\tG:\n"));
+                 hexdump (str, g.data, g.size, "\t\t\t");
 
-             buffer = gnutls_malloc (extlen);
-             if (!buffer)
-               {
-                 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
-                 continue;
-               }
+                 gnutls_free (p.data);
+                 gnutls_free (q.data);
+                 gnutls_free (g.data);
+                 gnutls_free (y.data);
 
-             err = gnutls_x509_crt_get_extension_data (cert, i,
-                                                       buffer, &extlen);
-             if (err < 0)
-               {
-                 gnutls_free (buffer);
-                 addf (str, "error: get_extension_data2: %s\n",
-                       gnutls_strerror (err));
-                 continue;
                }
+           }
+           break;
 
-             addf (str, _("\t\t\tASCII: "));
-             asciiprint (str, buffer, extlen);
-             addf (str, "\n");
+         default:
+           break;
+         }
+#endif
+      }
+  }
 
-             addf (str, _("\t\t\tHexdump: "));
-             hexprint (str, buffer, extlen);
-             adds (str, "\n");
+  /* Extensions. */
+  if (gnutls_x509_crt_get_version (cert) >= 3)
+    {
+      size_t i;
+      int err = 0;
 
-             gnutls_free (buffer);
-           }
-       }
+      print_extensions( str, "", TYPE_CRT, cert);
     }
 
   /* Signature. */
@@ -1551,4 +1620,242 @@ gnutls_x509_crl_print (gnutls_x509_crl_t crl,
   return 0;
 }
 
+static void
+print_crq (gnutls_string * str, gnutls_x509_crq_t cert)
+{
+  /* Version. */
+  {
+    int version = gnutls_x509_crq_get_version (cert);
+    if (version < 0)
+      addf (str, "error: get_version: %s\n", gnutls_strerror (version));
+    else
+      addf (str, _("\tVersion: %d\n"), version);
+  }
+
+  /* Subject */
+    {
+      char dn[1024];
+      size_t dn_size = sizeof (dn);
+      int err;
+
+      err = gnutls_x509_crq_get_dn (cert, dn, &dn_size);
+      if (err < 0)
+       addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
+      else
+       addf (str, _("\tSubject: %s\n"), dn);
+    }
+
+  /* SubjectPublicKeyInfo. */
+  {
+    int err;
+    unsigned int bits;
+
+    err = gnutls_x509_crq_get_pk_algorithm (cert, &bits);
+    if (err < 0)
+      addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
+    else
+      {
+       const char *name = gnutls_pk_algorithm_get_name (err);
+       if (name == NULL)
+         name = _("unknown");
+
+       addf (str, _("\tSubject Public Key Algorithm: %s\n"), name);
+       switch (err)
+         {
+         case GNUTLS_PK_RSA:
+           {
+             gnutls_datum_t m, e;
+
+             err = gnutls_x509_crq_get_key_rsa_raw (cert, &m, &e);
+             if (err < 0)
+               addf (str, "error: get_pk_rsa_raw: %s\n",
+                     gnutls_strerror (err));
+             else
+               {
+                 addf (str, _("\t\tModulus (bits %d):\n"), bits);
+                 hexdump (str, m.data, m.size, "\t\t\t");
+                 addf (str, _("\t\tExponent:\n"));
+                 hexdump (str, e.data, e.size, "\t\t\t");
+
+                 gnutls_free (m.data);
+                 gnutls_free (e.data);
+               }
+
+           }
+           break;
+#if 0 /* not implemented yet */
+         case GNUTLS_PK_DSA:
+           {
+             gnutls_datum_t p, q, g, y;
+
+             err = gnutls_x509_crq_get_key_dsa_raw (cert, &p, &q, &g, &y);
+             if (err < 0)
+               addf (str, "error: get_pk_dsa_raw: %s\n",
+                     gnutls_strerror (err));
+             else
+               {
+                 addf (str, _("\t\tPublic key (bits %d):\n"), bits);
+                 hexdump (str, y.data, y.size, "\t\t\t");
+                 addf (str, _("\t\tP:\n"));
+                 hexdump (str, p.data, p.size, "\t\t\t");
+                 addf (str, _("\t\tQ:\n"));
+                 hexdump (str, q.data, q.size, "\t\t\t");
+                 addf (str, _("\t\tG:\n"));
+                 hexdump (str, g.data, g.size, "\t\t\t");
+
+                 gnutls_free (p.data);
+                 gnutls_free (q.data);
+                 gnutls_free (g.data);
+                 gnutls_free (y.data);
+
+               }
+           }
+           break;
+#endif
+         default:
+           break;
+         }
+      }
+  }
+
+  /* parse attributes */
+    {
+      size_t i;
+      int err = 0;
+
+      for (i = 0;; i++)
+       {
+         char oid[128] = "";
+         size_t sizeof_oid = sizeof (oid);
+         int critical;
+         int extensions = 0;
+         int challenge = 0;
+
+         err = gnutls_x509_crq_get_attribute_info (cert, i,
+                                                   oid, &sizeof_oid);
+         if (err < 0)
+           {
+             if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+               break;
+             addf (str, "error: get_extension_info: %s\n",
+                   gnutls_strerror (err));
+             continue;
+           }
+
+         if (i == 0)
+           addf (str, _("\tAttributes:\n"));
+
+         if (strcmp (oid, "1.2.840.113549.1.9.14") == 0)
+           {
+             if (extensions)
+               {
+                 addf (str, "error: more than one extensionsRequest\n");
+                 continue;
+               }
+
+              print_extensions (str, "\t", TYPE_CRQ, cert);
+
+             extensions++;
+           }
+         else if (strcmp (oid, "1.2.840.113549.1.9.7") == 0)
+           {
+              char pass[1024];
+              size_t pass_size = sizeof (pass);
+              int err;
+              
+             if (challenge)
+               {
+                 addf (str, "error: more than one Challenge password attribute\n");
+                 continue;
+               }
+
+              err = gnutls_x509_crq_get_challenge_password (cert, pass, &pass_size);
+              if (err < 0)
+                addf (str, "error: get_challenge_password: %s\n", gnutls_strerror (err));
+              else
+                addf (str, _("\t\tChallenge password: %s\n"), pass);
+
+             challenge++;
+           }
+         else
+           {
+             char *buffer;
+             size_t extlen = 0;
+
+             addf (str, _("\t\tUnknown attribute %s:\n"), oid);
+
+             err = gnutls_x509_crq_get_attribute_data (cert, i,
+                                                       NULL, &extlen);
+             if (err < 0)
+               {
+                 addf (str, "error: get_attribute_data: %s\n",
+                       gnutls_strerror (err));
+                 continue;
+               }
+
+             buffer = gnutls_malloc (extlen);
+             if (!buffer)
+               {
+                 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
+                 continue;
+               }
+
+             err = gnutls_x509_crq_get_attribute_data (cert, i,
+                                                       buffer, &extlen);
+             if (err < 0)
+               {
+                 gnutls_free (buffer);
+                 addf (str, "error: get_attribute_data2: %s\n",
+                       gnutls_strerror (err));
+                 continue;
+               }
+
+             addf (str, _("\t\t\tASCII: "));
+             asciiprint (str, buffer, extlen);
+             addf (str, "\n");
+
+             addf (str, _("\t\t\tHexdump: "));
+             hexprint (str, buffer, extlen);
+             adds (str, "\n");
+
+             gnutls_free (buffer);
+           }
+       }
+    }
+}
+
+/**
+ * gnutls_x509_crq_print - Pretty print PKCS 10 certificate request
+ * @cert: The structure to be printed
+ * @format: Indicate the format to use
+ * @out: Newly allocated datum with zero terminated string.
+ *
+ * This function will pretty print a certificate request, suitable for
+ * display to a human.
+ *
+ * The output @out needs to be deallocate using gnutls_free().
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_x509_crq_print (gnutls_x509_crq_t crq,
+                      gnutls_certificate_print_formats_t format,
+                      gnutls_datum_t * out)
+{
+  gnutls_string str;
+
+  _gnutls_string_init (&str, gnutls_malloc, gnutls_realloc, gnutls_free);
+
+  _gnutls_string_append_str (&str, _("PKCS #10 Certificate Request Information:\n"));
+
+  print_crq (&str, crq);
+
+  _gnutls_string_append_data (&str, "\0", 1);
+  out->data = str.data;
+  out->size = strlen (str.data);
+
+  return 0;
+}
+
 #endif /* ENABLE_PKI */
index 8be70e1053e09a82fe5476ca57839a0ceabdab64..707ca81c0f149bfb8e5d056180b017cdd3bd2e9d 100644 (file)
@@ -904,8 +904,8 @@ is_type_printable (int type)
 /* returns the type and the name on success.
  * Type is also returned as a parameter in case of an error.
  */
-static int
-parse_general_name (ASN1_TYPE src, const char *src_name,
+int
+_gnutls_parse_general_name (ASN1_TYPE src, const char *src_name,
                    int seq, void *name, size_t * name_size,
                    unsigned int *ret_type, int othername_oid)
 {
@@ -1132,12 +1132,13 @@ get_subject_alt_name (gnutls_x509_crt_t cert,
     }
 
   result =
-    parse_general_name (c2, "", seq, ret, ret_size, ret_type, othername_oid);
+    _gnutls_parse_general_name (c2, "", seq, ret, ret_size, ret_type, othername_oid);
 
   asn1_delete_structure (&c2);
 
   if (result < 0)
     {
+      gnutls_assert();
       return result;
     }
 
@@ -1618,7 +1619,7 @@ gnutls_x509_crt_get_extension_info (gnutls_x509_crt_t cert, int indx,
 
   if (result == ASN1_ELEMENT_NOT_FOUND)
     return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
-  else if (result < 0)
+  else if (result != ASN1_SUCCESS)
     {
       gnutls_assert ();
       return _gnutls_asn2err (result);
@@ -1628,7 +1629,7 @@ gnutls_x509_crt_get_extension_info (gnutls_x509_crt_t cert, int indx,
            indx + 1);
   len = sizeof (str_critical);
   result = asn1_read_value (cert->cert, name, str_critical, &len);
-  if (result < 0)
+  if (result != ASN1_SUCCESS)
     {
       gnutls_assert ();
       return _gnutls_asn2err (result);
@@ -2437,7 +2438,7 @@ gnutls_x509_crt_get_crl_dist_points (gnutls_x509_crt_t cert,
    */
   _gnutls_str_cpy (name, sizeof (name), "?1.distributionPoint.fullName");
 
-  result = parse_general_name (c2, name, seq, ret, ret_size, NULL, 0);
+  result = _gnutls_parse_general_name (c2, name, seq, ret, ret_size, NULL, 0);
   if (result < 0)
     {
       asn1_delete_structure (&c2);
index 074bac072091c207e7a10563b0d6441ccf5e9ae4..cd921c3693e36a81f2d453da8e71fb67fe419fee 100644 (file)
@@ -161,6 +161,10 @@ int _gnutls_x509_get_dn_oid (ASN1_TYPE asn1_struct,
                             const char *asn1_rdn_name,
                             int indx, void *_oid, size_t * sizeof_oid);
 
+int _gnutls_parse_general_name (ASN1_TYPE src, const char *src_name,
+       int seq, void *name, size_t * name_size,
+        unsigned int *ret_type, int othername_oid);
+                                        
 /* dsa.c */
 
 
@@ -247,7 +251,9 @@ int _gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint,
                                        gnutls_datum_t * der_ext);
 
 /* mpi.c */
-
+int _gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert,
+                           bigint_t * params, int *params_size);
+                           
 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);
@@ -348,4 +354,10 @@ int _pkcs12_decode_crt_bag (gnutls_pkcs12_bag_type_t type,
 int _pkcs12_encode_crt_bag (gnutls_pkcs12_bag_type_t type,
                            const gnutls_datum_t * raw, gnutls_datum_t * out);
 
+/* crq */
+int _gnutls_x509_crq_set_extension (gnutls_x509_crq_t crq,
+                               const char *ext_id,
+                               const gnutls_datum_t * ext_data,
+                               unsigned int critical);
+
 #endif
index bbc05c28aaaec54b2b2dbb099da12a7e51a7ca56..ec9fb459ee4c7e86219d41cb0e4bb62644f78ae4 100644 (file)
@@ -37,6 +37,7 @@
 /* Gnulib portability files. */
 #include <getpass.h>
 #include "readline.h"
+#include "certtool-common.h"
 
 extern int batch;
 
@@ -772,7 +773,7 @@ static int string_to_ip( unsigned char *ip, const char * str)
 }
 
 void
-get_ip_addr_set (gnutls_x509_crt_t crt)
+get_ip_addr_set (int type, void* crt)
 {
   int ret, i;
   unsigned char ip[16];
@@ -791,7 +792,11 @@ get_ip_addr_set (gnutls_x509_crt_t crt)
             exit(1);
           }
 
-         ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_IPADDRESS,
+         if (type == TYPE_CRT)
+           ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_IPADDRESS,
+           ip, len, GNUTLS_FSAN_APPEND);
+          else
+           ret = gnutls_x509_crq_set_subject_alt_name( crt, GNUTLS_SAN_IPADDRESS,
            ip, len, GNUTLS_FSAN_APPEND);
            
           if (ret < 0) break;
@@ -801,15 +806,20 @@ get_ip_addr_set (gnutls_x509_crt_t crt)
     {
       const char *p;
       
-      p = read_str ("Enter the dnsName of the subject of the certificate: ");
+      p = read_str ("Enter the IP address of the subject of the certificate: ");
       if (!p) return;
 
-        len = string_to_ip( ip, cfg.ip_addr[i]);
+        len = string_to_ip( ip, p);
         if (len <= 0) {
             fprintf(stderr, "Error parsing address: %s\n", cfg.ip_addr[i]);
             exit(1);
         }
-        ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_IPADDRESS,
+
+        if (type == TYPE_CRT)
+           ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_IPADDRESS,
+           ip, len, GNUTLS_FSAN_APPEND);
+        else
+           ret = gnutls_x509_crq_set_subject_alt_name( crt, GNUTLS_SAN_IPADDRESS,
            ip, len, GNUTLS_FSAN_APPEND);
     }
 
@@ -822,7 +832,7 @@ get_ip_addr_set (gnutls_x509_crt_t crt)
 
 
 void
-get_email_set (gnutls_x509_crt_t crt)
+get_email_set (int type, void* crt)
 {
   int ret, i;
 
@@ -833,8 +843,12 @@ get_email_set (gnutls_x509_crt_t crt)
 
       for (i = 0; cfg.email[i] != NULL; i ++)
        {
-         ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_RFC822NAME,
-           cfg.email[i], strlen(cfg.email[i]), GNUTLS_FSAN_APPEND);
+         if (type == TYPE_CRT)
+           ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_RFC822NAME,
+             cfg.email[i], strlen(cfg.email[i]), GNUTLS_FSAN_APPEND);
+          else
+           ret = gnutls_x509_crq_set_subject_alt_name( crt, GNUTLS_SAN_RFC822NAME,
+             cfg.email[i], strlen(cfg.email[i]), GNUTLS_FSAN_APPEND);
            
           if (ret < 0) break;
        }
@@ -846,8 +860,12 @@ get_email_set (gnutls_x509_crt_t crt)
       p = read_str ("Enter the e-mail of the subject of the certificate: ");
       if (!p) return;
 
-      ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_RFC822NAME,
-        p, strlen(p), GNUTLS_FSAN_APPEND);
+      if (type == TYPE_CRT)
+        ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_RFC822NAME,
+          p, strlen(p), GNUTLS_FSAN_APPEND);
+      else
+        ret = gnutls_x509_crq_set_subject_alt_name( crt, GNUTLS_SAN_RFC822NAME,
+          p, strlen(p), GNUTLS_FSAN_APPEND);
     }
 
   if (ret < 0)
@@ -858,7 +876,7 @@ get_email_set (gnutls_x509_crt_t crt)
 }
 
 void
-get_dns_name_set (gnutls_x509_crt_t crt)
+get_dns_name_set (int type, void* crt)
 {
   int ret, i;
 
@@ -869,8 +887,12 @@ get_dns_name_set (gnutls_x509_crt_t crt)
 
       for (i = 0; cfg.dns_name[i] != NULL; i ++)
        {
-         ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_DNSNAME,
-           cfg.dns_name[i], strlen(cfg.dns_name[i]), GNUTLS_FSAN_APPEND);
+          if (type == TYPE_CRT)
+            ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_DNSNAME,
+             cfg.dns_name[i], strlen(cfg.dns_name[i]), GNUTLS_FSAN_APPEND);
+          else
+            ret = gnutls_x509_crq_set_subject_alt_name( crt, GNUTLS_SAN_DNSNAME,
+             cfg.dns_name[i], strlen(cfg.dns_name[i]), GNUTLS_FSAN_APPEND);
            
           if (ret < 0) break;
        }
@@ -882,8 +904,12 @@ get_dns_name_set (gnutls_x509_crt_t crt)
       p = read_str ("Enter the dnsName of the subject of the certificate: ");
       if (!p) return;
 
-      ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_DNSNAME,
-        p, strlen(p), GNUTLS_FSAN_APPEND);
+      if (type == TYPE_CRT)
+        ret = gnutls_x509_crt_set_subject_alt_name( crt, GNUTLS_SAN_DNSNAME,
+          p, strlen(p), GNUTLS_FSAN_APPEND);
+      else
+        ret = gnutls_x509_crq_set_subject_alt_name( crt, GNUTLS_SAN_DNSNAME,
+          p, strlen(p), GNUTLS_FSAN_APPEND);
     }
 
   if (ret < 0)
index 5fa6be45dd29c7bc0c4e473a123f305ade69187b..1820b6799b3bd04dec51e8c5e3b91ed12ba5e0f4 100644 (file)
@@ -50,9 +50,9 @@ int get_crl_sign_status (void);
 int get_cert_sign_status (void);
 int get_encrypt_status (int server);
 int get_sign_status (int server);
-void get_ip_addr_set (gnutls_x509_crt_t crt);
-void get_dns_name_set (gnutls_x509_crt_t crt);
-void get_email_set (gnutls_x509_crt_t crt);
+void get_ip_addr_set (int type, void* crt);
+void get_dns_name_set (int type, void* crt);
+void get_email_set (int type, void* crt);
 
 
 void get_cn_crq_set (gnutls_x509_crq_t crq);
diff --git a/src/certtool-common.h b/src/certtool-common.h
new file mode 100644 (file)
index 0000000..468e2cd
--- /dev/null
@@ -0,0 +1,28 @@
+enum {
+    ACTION_SELF_SIGNED,
+    ACTION_GENERATE_PRIVKEY,
+    ACTION_CERT_INFO,
+    ACTION_GENERATE_REQUEST,
+    ACTION_GENERATE_CERTIFICATE,
+    ACTION_VERIFY_CHAIN,
+    ACTION_PRIVKEY_INFO,
+    ACTION_UPDATE_CERTIFICATE,
+    ACTION_TO_PKCS12,
+    ACTION_PKCS12_INFO,
+    ACTION_GENERATE_DH,
+    ACTION_GET_DH,
+    ACTION_CRL_INFO,
+    ACTION_P7_INFO,
+    ACTION_GENERATE_CRL,
+    ACTION_VERIFY_CRL,
+    ACTION_SMIME_TO_P7,
+    ACTION_GENERATE_PROXY,
+    ACTION_GENERATE_PKCS8,
+    ACTION_PGP_INFO,
+    ACTION_PGP_PRIVKEY_INFO,
+    ACTION_RING_INFO,
+    ACTION_REQUEST
+};
+
+#define TYPE_CRT 1
+#define TYPE_CRQ 2
index 2633f3208c52235876f57f095e64dc5da03c934d..5a218f8e72ea15760cfb80435aecabb9e14c7a79 100644 (file)
@@ -13,6 +13,8 @@
 
 void certtool_version(void);
 
+#include "certtool-common.h"
+
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -150,6 +152,7 @@ void gaa_help(void)
        __gaa_helpsingle(0, "pgp-certificate-info", "", "Print information on a OpenPGP certificate.");
        __gaa_helpsingle(0, "pgp-ring-info", "", "Print information on a keyring structure.");
        __gaa_helpsingle('l', "crl-info", "", "Print information on a CRL.");
+       __gaa_helpsingle(0, "crq-info", "", "Print information on a Certificate Request.");
        __gaa_helpsingle(0, "p12-info", "", "Print information on a PKCS #12 structure.");
        __gaa_helpsingle(0, "p7-info", "", "Print information on a PKCS #7 structure.");
        __gaa_helpsingle(0, "smime-to-p7", "", "Convert S/MIME to PKCS #7 structure.");
@@ -189,49 +192,49 @@ typedef struct _gaainfo gaainfo;
 
 struct _gaainfo
 {
-#line 123 "certtool.gaa"
+#line 127 "certtool.gaa"
        int debug;
-#line 119 "certtool.gaa"
+#line 123 "certtool.gaa"
        char *template;
-#line 116 "certtool.gaa"
+#line 120 "certtool.gaa"
        char *infile;
-#line 113 "certtool.gaa"
+#line 117 "certtool.gaa"
        char *outfile;
-#line 110 "certtool.gaa"
+#line 114 "certtool.gaa"
        int quick_random;
-#line 107 "certtool.gaa"
+#line 111 "certtool.gaa"
        int bits;
-#line 103 "certtool.gaa"
+#line 107 "certtool.gaa"
        int outcert_format;
-#line 99 "certtool.gaa"
+#line 103 "certtool.gaa"
        int incert_format;
-#line 96 "certtool.gaa"
+#line 100 "certtool.gaa"
        int export;
-#line 93 "certtool.gaa"
+#line 97 "certtool.gaa"
        char *hash;
-#line 90 "certtool.gaa"
+#line 94 "certtool.gaa"
        int dsa;
-#line 87 "certtool.gaa"
+#line 91 "certtool.gaa"
        int pkcs8;
-#line 80 "certtool.gaa"
+#line 84 "certtool.gaa"
        int v1_cert;
-#line 77 "certtool.gaa"
+#line 81 "certtool.gaa"
        int fix_key;
-#line 54 "certtool.gaa"
+#line 56 "certtool.gaa"
        char *pass;
-#line 51 "certtool.gaa"
+#line 53 "certtool.gaa"
        char *ca;
-#line 48 "certtool.gaa"
+#line 50 "certtool.gaa"
        char *ca_privkey;
-#line 45 "certtool.gaa"
+#line 47 "certtool.gaa"
        char *cert;
-#line 42 "certtool.gaa"
+#line 44 "certtool.gaa"
        char *request;
-#line 39 "certtool.gaa"
+#line 41 "certtool.gaa"
        char *privkey;
-#line 17 "certtool.gaa"
+#line 19 "certtool.gaa"
        int action;
-#line 16 "certtool.gaa"
+#line 18 "certtool.gaa"
        int privkey_op;
 
 #line 114 "gaa.skel"
@@ -287,7 +290,7 @@ static int gaa_error = 0;
 #define GAA_MULTIPLE_OPTION     3
 
 #define GAA_REST                0
-#define GAA_NB_OPTION           46
+#define GAA_NB_OPTION           47
 #define GAAOPTID_version       1
 #define GAAOPTID_help  2
 #define GAAOPTID_debug 3
@@ -313,27 +316,28 @@ static int gaa_error = 0;
 #define GAAOPTID_smime_to_p7   23
 #define GAAOPTID_p7_info       24
 #define GAAOPTID_p12_info      25
-#define GAAOPTID_crl_info      26
-#define GAAOPTID_pgp_ring_info 27
-#define GAAOPTID_pgp_certificate_info  28
-#define GAAOPTID_certificate_info      29
-#define GAAOPTID_password      30
-#define GAAOPTID_load_ca_certificate   31
-#define GAAOPTID_load_ca_privkey       32
-#define GAAOPTID_load_certificate      33
-#define GAAOPTID_load_request  34
-#define GAAOPTID_load_privkey  35
-#define GAAOPTID_get_dh_params 36
-#define GAAOPTID_generate_dh_params    37
-#define GAAOPTID_verify_crl    38
-#define GAAOPTID_verify_chain  39
-#define GAAOPTID_generate_request      40
-#define GAAOPTID_generate_privkey      41
-#define GAAOPTID_update_certificate    42
-#define GAAOPTID_generate_crl  43
-#define GAAOPTID_generate_proxy        44
-#define GAAOPTID_generate_certificate  45
-#define GAAOPTID_generate_self_signed  46
+#define GAAOPTID_crq_info      26
+#define GAAOPTID_crl_info      27
+#define GAAOPTID_pgp_ring_info 28
+#define GAAOPTID_pgp_certificate_info  29
+#define GAAOPTID_certificate_info      30
+#define GAAOPTID_password      31
+#define GAAOPTID_load_ca_certificate   32
+#define GAAOPTID_load_ca_privkey       33
+#define GAAOPTID_load_certificate      34
+#define GAAOPTID_load_request  35
+#define GAAOPTID_load_privkey  36
+#define GAAOPTID_get_dh_params 37
+#define GAAOPTID_generate_dh_params    38
+#define GAAOPTID_verify_crl    39
+#define GAAOPTID_verify_chain  40
+#define GAAOPTID_generate_request      41
+#define GAAOPTID_generate_privkey      42
+#define GAAOPTID_update_certificate    43
+#define GAAOPTID_generate_crl  44
+#define GAAOPTID_generate_proxy        45
+#define GAAOPTID_generate_certificate  46
+#define GAAOPTID_generate_self_signed  47
 
 #line 168 "gaa.skel"
 
@@ -493,12 +497,31 @@ static int gaa_getint(char *arg)
     return tmp;
 }
 
+static char gaa_getchar(char *arg)
+{
+    if(strlen(arg) != 1)
+    {
+        printf("Option %s: '%s' isn't an character\n", gaa_current_option, arg);
+        GAAERROR(-1);
+    }
+    return arg[0];
+}
 
 static char* gaa_getstr(char *arg)
 {
     return arg;
 }
-
+static float gaa_getfloat(char *arg)
+{
+    float tmp;
+    char a;
+    if(sscanf(arg, "%f%c", &tmp, &a) < 1)
+    {
+        printf("Option %s: '%s' isn't a float number\n", gaa_current_option, arg);
+        GAAERROR(-1);
+    }
+    return tmp;
+}
 /* option structures */
 
 struct GAAOPTION_debug 
@@ -635,6 +658,7 @@ static int gaa_get_option_num(char *str, int status)
                        GAA_CHECK1STR("", GAAOPTID_smime_to_p7);
                        GAA_CHECK1STR("", GAAOPTID_p7_info);
                        GAA_CHECK1STR("", GAAOPTID_p12_info);
+                       GAA_CHECK1STR("", GAAOPTID_crq_info);
                        GAA_CHECK1STR("l", GAAOPTID_crl_info);
                        GAA_CHECK1STR("", GAAOPTID_pgp_ring_info);
                        GAA_CHECK1STR("", GAAOPTID_pgp_certificate_info);
@@ -679,6 +703,7 @@ static int gaa_get_option_num(char *str, int status)
                        GAA_CHECKSTR("smime-to-p7", GAAOPTID_smime_to_p7);
                        GAA_CHECKSTR("p7-info", GAAOPTID_p7_info);
                        GAA_CHECKSTR("p12-info", GAAOPTID_p12_info);
+                       GAA_CHECKSTR("crq-info", GAAOPTID_crq_info);
                        GAA_CHECKSTR("crl-info", GAAOPTID_crl_info);
                        GAA_CHECKSTR("pgp-ring-info", GAAOPTID_pgp_ring_info);
                        GAA_CHECKSTR("pgp-certificate-info", GAAOPTID_pgp_certificate_info);
@@ -746,14 +771,14 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
     {
        case GAAOPTID_version:
        OK = 0;
-#line 128 "certtool.gaa"
+#line 132 "certtool.gaa"
 { certtool_version(); exit(0); ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_help:
        OK = 0;
-#line 126 "certtool.gaa"
+#line 130 "certtool.gaa"
 { gaa_help(); exit(0); ;};
 
                return GAA_OK;
@@ -763,7 +788,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_debug.arg1, gaa_getint, GAATMP_debug.size1);
                gaa_index++;
-#line 124 "certtool.gaa"
+#line 128 "certtool.gaa"
 { gaaval->debug = GAATMP_debug.arg1 ;};
 
                return GAA_OK;
@@ -773,7 +798,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_template.arg1, gaa_getstr, GAATMP_template.size1);
                gaa_index++;
-#line 120 "certtool.gaa"
+#line 124 "certtool.gaa"
 { gaaval->template = GAATMP_template.arg1 ;};
 
                return GAA_OK;
@@ -783,7 +808,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_infile.arg1, gaa_getstr, GAATMP_infile.size1);
                gaa_index++;
-#line 117 "certtool.gaa"
+#line 121 "certtool.gaa"
 { gaaval->infile = GAATMP_infile.arg1 ;};
 
                return GAA_OK;
@@ -793,14 +818,14 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_outfile.arg1, gaa_getstr, GAATMP_outfile.size1);
                gaa_index++;
-#line 114 "certtool.gaa"
+#line 118 "certtool.gaa"
 { gaaval->outfile = GAATMP_outfile.arg1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_disable_quick_random:
        OK = 0;
-#line 111 "certtool.gaa"
+#line 115 "certtool.gaa"
 { gaaval->quick_random = 0; ;};
 
                return GAA_OK;
@@ -810,42 +835,42 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_bits.arg1, gaa_getint, GAATMP_bits.size1);
                gaa_index++;
-#line 108 "certtool.gaa"
+#line 112 "certtool.gaa"
 { gaaval->bits = GAATMP_bits.arg1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_outraw:
        OK = 0;
-#line 105 "certtool.gaa"
+#line 109 "certtool.gaa"
 { gaaval->outcert_format=1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_outder:
        OK = 0;
-#line 104 "certtool.gaa"
+#line 108 "certtool.gaa"
 { gaaval->outcert_format=1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_inraw:
        OK = 0;
-#line 101 "certtool.gaa"
+#line 105 "certtool.gaa"
 { gaaval->incert_format=1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_inder:
        OK = 0;
-#line 100 "certtool.gaa"
+#line 104 "certtool.gaa"
 { gaaval->incert_format=1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_export_ciphers:
        OK = 0;
-#line 97 "certtool.gaa"
+#line 101 "certtool.gaa"
 { gaaval->export=1 ;};
 
                return GAA_OK;
@@ -855,113 +880,120 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_hash.arg1, gaa_getstr, GAATMP_hash.size1);
                gaa_index++;
-#line 94 "certtool.gaa"
+#line 98 "certtool.gaa"
 { gaaval->hash = GAATMP_hash.arg1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_dsa:
        OK = 0;
-#line 91 "certtool.gaa"
+#line 95 "certtool.gaa"
 { gaaval->dsa=1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_pkcs8:
        OK = 0;
-#line 88 "certtool.gaa"
+#line 92 "certtool.gaa"
 { gaaval->pkcs8=1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_to_p8:
        OK = 0;
-#line 85 "certtool.gaa"
-{ gaaval->action = 18; ;};
+#line 89 "certtool.gaa"
+{ gaaval->action = ACTION_GENERATE_PKCS8; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_to_p12:
        OK = 0;
-#line 83 "certtool.gaa"
-{ gaaval->action = 8; ;};
+#line 87 "certtool.gaa"
+{ gaaval->action = ACTION_TO_PKCS12; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_v1:
        OK = 0;
-#line 81 "certtool.gaa"
+#line 85 "certtool.gaa"
 { gaaval->v1_cert = 1; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_fix_key:
        OK = 0;
-#line 78 "certtool.gaa"
+#line 82 "certtool.gaa"
 { gaaval->privkey_op=1; gaaval->fix_key = 1; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_pgp_key_info:
        OK = 0;
-#line 75 "certtool.gaa"
-{ gaaval->privkey_op=1; gaaval->action = 20; ;};
+#line 79 "certtool.gaa"
+{ gaaval->privkey_op=1; gaaval->action = ACTION_PGP_PRIVKEY_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_key_info:
        OK = 0;
-#line 73 "certtool.gaa"
-{ gaaval->privkey_op=1; gaaval->action = 6; ;};
+#line 77 "certtool.gaa"
+{ gaaval->privkey_op=1; gaaval->action = ACTION_PRIVKEY_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_smime_to_p7:
        OK = 0;
-#line 69 "certtool.gaa"
-{ gaaval->action = 15; ;};
+#line 73 "certtool.gaa"
+{ gaaval->action = ACTION_SMIME_TO_P7; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_p7_info:
        OK = 0;
-#line 67 "certtool.gaa"
-{ gaaval->action = 12; ;};
+#line 71 "certtool.gaa"
+{ gaaval->action = ACTION_P7_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_p12_info:
        OK = 0;
-#line 65 "certtool.gaa"
-{ gaaval->action = 9; ;};
+#line 69 "certtool.gaa"
+{ gaaval->action = ACTION_PKCS12_INFO; ;};
+
+               return GAA_OK;
+               break;
+       case GAAOPTID_crq_info:
+       OK = 0;
+#line 67 "certtool.gaa"
+{ gaaval->action = ACTION_REQUEST; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_crl_info:
        OK = 0;
-#line 63 "certtool.gaa"
-{ gaaval->action = 11; ;};
+#line 65 "certtool.gaa"
+{ gaaval->action = ACTION_CRL_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_pgp_ring_info:
        OK = 0;
-#line 61 "certtool.gaa"
-{ gaaval->action = 21; ;};
+#line 63 "certtool.gaa"
+{ gaaval->action = ACTION_RING_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_pgp_certificate_info:
        OK = 0;
-#line 59 "certtool.gaa"
-{ gaaval->action = 19; ;};
+#line 61 "certtool.gaa"
+{ gaaval->action = ACTION_PGP_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_certificate_info:
        OK = 0;
-#line 57 "certtool.gaa"
-{ gaaval->action = 2; ;};
+#line 59 "certtool.gaa"
+{ gaaval->action = ACTION_CERT_INFO; ;};
 
                return GAA_OK;
                break;
@@ -970,7 +1002,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_password.arg1, gaa_getstr, GAATMP_password.size1);
                gaa_index++;
-#line 55 "certtool.gaa"
+#line 57 "certtool.gaa"
 { gaaval->pass = GAATMP_password.arg1 ;};
 
                return GAA_OK;
@@ -980,7 +1012,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_load_ca_certificate.arg1, gaa_getstr, GAATMP_load_ca_certificate.size1);
                gaa_index++;
-#line 52 "certtool.gaa"
+#line 54 "certtool.gaa"
 { gaaval->ca = GAATMP_load_ca_certificate.arg1 ;};
 
                return GAA_OK;
@@ -990,7 +1022,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_load_ca_privkey.arg1, gaa_getstr, GAATMP_load_ca_privkey.size1);
                gaa_index++;
-#line 49 "certtool.gaa"
+#line 51 "certtool.gaa"
 { gaaval->ca_privkey = GAATMP_load_ca_privkey.arg1 ;};
 
                return GAA_OK;
@@ -1000,7 +1032,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_load_certificate.arg1, gaa_getstr, GAATMP_load_certificate.size1);
                gaa_index++;
-#line 46 "certtool.gaa"
+#line 48 "certtool.gaa"
 { gaaval->cert = GAATMP_load_certificate.arg1 ;};
 
                return GAA_OK;
@@ -1010,7 +1042,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_load_request.arg1, gaa_getstr, GAATMP_load_request.size1);
                gaa_index++;
-#line 43 "certtool.gaa"
+#line 45 "certtool.gaa"
 { gaaval->request = GAATMP_load_request.arg1 ;};
 
                return GAA_OK;
@@ -1020,85 +1052,85 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_load_privkey.arg1, gaa_getstr, GAATMP_load_privkey.size1);
                gaa_index++;
-#line 40 "certtool.gaa"
+#line 42 "certtool.gaa"
 { gaaval->privkey = GAATMP_load_privkey.arg1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_get_dh_params:
        OK = 0;
-#line 37 "certtool.gaa"
-{ gaaval->action=16; ;};
+#line 39 "certtool.gaa"
+{ gaaval->action=ACTION_GET_DH; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_generate_dh_params:
        OK = 0;
-#line 36 "certtool.gaa"
-{ gaaval->action=10; ;};
+#line 38 "certtool.gaa"
+{ gaaval->action=ACTION_GENERATE_DH; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_verify_crl:
        OK = 0;
-#line 34 "certtool.gaa"
-{ gaaval->action=14; ;};
+#line 36 "certtool.gaa"
+{ gaaval->action=ACTION_VERIFY_CRL; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_verify_chain:
        OK = 0;
-#line 32 "certtool.gaa"
-{ gaaval->action=5; ;};
+#line 34 "certtool.gaa"
+{ gaaval->action=ACTION_VERIFY_CHAIN; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_generate_request:
        OK = 0;
-#line 30 "certtool.gaa"
-{ gaaval->action=3; ;};
+#line 32 "certtool.gaa"
+{ gaaval->action=ACTION_GENERATE_REQUEST; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_generate_privkey:
        OK = 0;
-#line 28 "certtool.gaa"
-{ gaaval->privkey_op=1; gaaval->action=1; ;};
+#line 30 "certtool.gaa"
+{ gaaval->privkey_op=1; gaaval->action=ACTION_GENERATE_PRIVKEY; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_update_certificate:
        OK = 0;
-#line 26 "certtool.gaa"
-{ gaaval->action=7; ;};
+#line 28 "certtool.gaa"
+{ gaaval->action=ACTION_UPDATE_CERTIFICATE; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_generate_crl:
        OK = 0;
-#line 24 "certtool.gaa"
-{ gaaval->action=13; ;};
+#line 26 "certtool.gaa"
+{ gaaval->action=ACTION_GENERATE_CRL; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_generate_proxy:
        OK = 0;
-#line 22 "certtool.gaa"
-{ gaaval->action=17; ;};
+#line 24 "certtool.gaa"
+{ gaaval->action=ACTION_GENERATE_PROXY; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_generate_certificate:
        OK = 0;
-#line 20 "certtool.gaa"
-{ gaaval->action=4; ;};
+#line 22 "certtool.gaa"
+{ gaaval->action=ACTION_GENERATE_CERTIFICATE; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_generate_self_signed:
        OK = 0;
-#line 18 "certtool.gaa"
-{ gaaval->action=0; ;};
+#line 20 "certtool.gaa"
+{ gaaval->action=ACTION_SELF_SIGNED; ;};
 
                return GAA_OK;
                break;
@@ -1126,7 +1158,7 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
     if(inited == 0)
     {
 
-#line 130 "certtool.gaa"
+#line 134 "certtool.gaa"
 { gaaval->bits = 2048; gaaval->pkcs8 = 0; gaaval->privkey = NULL; gaaval->ca=NULL; gaaval->ca_privkey = NULL; 
        gaaval->debug=1; gaaval->request = NULL; gaaval->infile = NULL; gaaval->outfile = NULL; gaaval->cert = NULL; 
        gaaval->incert_format = 0; gaaval->outcert_format = 0; gaaval->action=-1; gaaval->pass = NULL; gaaval->v1_cert = 0;
@@ -1279,7 +1311,7 @@ static int gaa_internal_get_next_str(FILE *file, gaa_str_node *tmp_str, int argc
 
         len++;
         a = fgetc( file);
-        if(a==EOF) return 0; /* a = ' '; */
+        if(a==EOF) return 0; //a = ' ';
     }
 
     len += 1;
index a95546562d6457ca92d955ba2abe29a7f7e10b1b..a8ae82469e34abd3d9f9b05bd6fa8a2bd7a6a643 100644 (file)
@@ -8,49 +8,49 @@ typedef struct _gaainfo gaainfo;
 
 struct _gaainfo
 {
-#line 123 "certtool.gaa"
+#line 127 "certtool.gaa"
        int debug;
-#line 119 "certtool.gaa"
+#line 123 "certtool.gaa"
        char *template;
-#line 116 "certtool.gaa"
+#line 120 "certtool.gaa"
        char *infile;
-#line 113 "certtool.gaa"
+#line 117 "certtool.gaa"
        char *outfile;
-#line 110 "certtool.gaa"
+#line 114 "certtool.gaa"
        int quick_random;
-#line 107 "certtool.gaa"
+#line 111 "certtool.gaa"
        int bits;
-#line 103 "certtool.gaa"
+#line 107 "certtool.gaa"
        int outcert_format;
-#line 99 "certtool.gaa"
+#line 103 "certtool.gaa"
        int incert_format;
-#line 96 "certtool.gaa"
+#line 100 "certtool.gaa"
        int export;
-#line 93 "certtool.gaa"
+#line 97 "certtool.gaa"
        char *hash;
-#line 90 "certtool.gaa"
+#line 94 "certtool.gaa"
        int dsa;
-#line 87 "certtool.gaa"
+#line 91 "certtool.gaa"
        int pkcs8;
-#line 80 "certtool.gaa"
+#line 84 "certtool.gaa"
        int v1_cert;
-#line 77 "certtool.gaa"
+#line 81 "certtool.gaa"
        int fix_key;
-#line 54 "certtool.gaa"
+#line 56 "certtool.gaa"
        char *pass;
-#line 51 "certtool.gaa"
+#line 53 "certtool.gaa"
        char *ca;
-#line 48 "certtool.gaa"
+#line 50 "certtool.gaa"
        char *ca_privkey;
-#line 45 "certtool.gaa"
+#line 47 "certtool.gaa"
        char *cert;
-#line 42 "certtool.gaa"
+#line 44 "certtool.gaa"
        char *request;
-#line 39 "certtool.gaa"
+#line 41 "certtool.gaa"
        char *privkey;
-#line 17 "certtool.gaa"
+#line 19 "certtool.gaa"
        int action;
-#line 16 "certtool.gaa"
+#line 18 "certtool.gaa"
        int privkey_op;
 
 #line 114 "gaa.skel"
index fe57304d86a3d04c4bc9653c8fabf8b0ac849cad..ba7a87dd299e88318e9311522278849c859397cf 100644 (file)
@@ -30,6 +30,7 @@
 #include <gnutls/openpgp.h>
 #include <time.h>
 #include "certtool-gaa.h"
+#include "certtool-common.h"
 #include <gnutls/pkcs12.h>
 #include <unistd.h>
 #include <certtool-cfg.h>
@@ -48,6 +49,7 @@
 static void print_crl_info (gnutls_x509_crl_t crl, FILE * out);
 int generate_prime (int bits, int how);
 void pkcs7_info (void);
+void crq_info (void);
 void smime_to_pkcs7 (void);
 void pkcs12_info (void);
 void generate_pkcs12 (void);
@@ -406,8 +408,8 @@ generate_certificate (gnutls_x509_privkey_t * ret_key,
 
          if (!proxy)
            {
-             get_dns_name_set( crt);
-             get_ip_addr_set( crt);
+             get_dns_name_set( TYPE_CRT, crt);
+             get_ip_addr_set( TYPE_CRT, crt);
            }
 
          result =
@@ -418,7 +420,7 @@ generate_certificate (gnutls_x509_privkey_t * ret_key,
        }
       else if (!proxy)
        {
-         get_email_set( crt);
+         get_email_set( TYPE_CRT, crt);
        }
 
       if (!ca_status || server)
@@ -931,74 +933,77 @@ gaa_parser (int argc, char **argv)
 
   switch (info.action)
     {
-    case 0:
+    case ACTION_SELF_SIGNED:
       generate_self_signed ();
       break;
-    case 1:
+    case ACTION_GENERATE_PRIVKEY:
       generate_private_key ();
       break;
-    case 2:
+    case ACTION_CERT_INFO:
       certificate_info ();
       break;
-    case 3:
+    case ACTION_GENERATE_REQUEST:
       generate_request ();
       break;
-    case 4:
+    case ACTION_GENERATE_CERTIFICATE:
       generate_signed_certificate ();
       break;
-    case 5:
+    case ACTION_VERIFY_CHAIN:
       verify_chain ();
       break;
-    case 6:
+    case ACTION_PRIVKEY_INFO:
       privkey_info ();
       break;
-    case 7:
+    case ACTION_UPDATE_CERTIFICATE:
       update_signed_certificate ();
       break;
-    case 8:
+    case ACTION_TO_PKCS12:
       generate_pkcs12 ();
       break;
-    case 9:
+    case ACTION_PKCS12_INFO:
       pkcs12_info ();
       break;
-    case 10:
+    case ACTION_GENERATE_DH:
       generate_prime (info.bits, 1);
       break;
-    case 16:
+    case ACTION_GET_DH:
       generate_prime (info.bits, 0);
       break;
-    case 11:
+    case ACTION_CRL_INFO:
       crl_info ();
       break;
-    case 12:
+    case ACTION_P7_INFO:
       pkcs7_info ();
       break;
-    case 13:
+    case ACTION_GENERATE_CRL:
       generate_signed_crl ();
       break;
-    case 14:
+    case ACTION_VERIFY_CRL:
       verify_crl ();
       break;
-    case 15:
+    case ACTION_SMIME_TO_P7:
       smime_to_pkcs7 ();
       break;
-    case 17:
+    case ACTION_GENERATE_PROXY:
       generate_proxy_certificate ();
       break;
-    case 18:
+    case ACTION_GENERATE_PKCS8:
       generate_pkcs8 ();
       break;
 #ifdef ENABLE_OPENPGP
-    case 19:
+    case ACTION_PGP_INFO:
       pgp_certificate_info ();
       break;
-    case 20:
+    case ACTION_PGP_PRIVKEY_INFO:
       pgp_privkey_info ();
       break;
-    case 21:
+    case ACTION_RING_INFO:
       pgp_ring_info ();
       break;
 #endif
+    case ACTION_REQUEST:
+      crq_info();
+      break;
     default:
       gaa_help ();
       exit (0);
@@ -1390,6 +1395,59 @@ crl_info (void)
   gnutls_x509_crl_deinit (crl);
 }
 
+static void
+print_crq_info (gnutls_x509_crq_t crq, FILE * out)
+{
+  gnutls_datum_t info;
+  int ret;
+  size_t size;
+
+  ret = gnutls_x509_crq_print (crq, GNUTLS_CRT_PRINT_FULL, &info);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "crq_print: %s", gnutls_strerror (ret));
+
+  fprintf (out, "%s\n", info.data);
+
+  gnutls_free (info.data);
+
+  size = sizeof (buffer);
+  ret = gnutls_x509_crq_export (crq, GNUTLS_X509_FMT_PEM, buffer, &size);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "crq_export: %s", gnutls_strerror (ret));
+
+  fwrite (buffer, 1, size, outfile);
+}
+
+void
+crq_info (void)
+{
+  gnutls_x509_crq_t crq;
+  int ret;
+  size_t size;
+  gnutls_datum_t pem;
+
+  ret = gnutls_x509_crq_init (&crq);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "crq_init: %s", gnutls_strerror (ret));
+
+  pem.data = fread_file (infile, &size);
+  pem.size = size;
+
+  if (!pem.data)
+    error (EXIT_FAILURE, errno, "%s", info.infile ? info.infile :
+          "standard input");
+
+  ret = gnutls_x509_crq_import (crq, &pem, info.incert_format);
+
+  free (pem.data);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "Import error: %s", gnutls_strerror (ret));
+
+  print_crq_info (crq, outfile);
+
+  gnutls_x509_crq_deinit (crq);
+}
+
 void
 privkey_info (void)
 {
@@ -1766,9 +1824,10 @@ generate_request (void)
 {
   gnutls_x509_crq_t crq;
   gnutls_x509_privkey_t key;
-  int ret;
+  int ret, ca_status, path_len;
   const char *pass;
   size_t size;
+  unsigned int usage;
 
   fprintf (stderr, "Generating a PKCS #10 certificate request...\n");
 
@@ -1797,15 +1856,57 @@ generate_request (void)
   get_uid_crq_set (crq);
   get_oid_crq_set (crq);
 
+  get_dns_name_set( TYPE_CRQ, crq);
+  get_ip_addr_set( TYPE_CRQ, crq);
+  get_email_set( TYPE_CRQ, crq);
+
   pass = get_challenge_pass ();
 
-  if (pass != NULL)
+  if (pass != NULL && pass[0] != 0)
     {
       ret = gnutls_x509_crq_set_challenge_password (crq, pass);
       if (ret < 0)
        error (EXIT_FAILURE, 0, "set_pass: %s", gnutls_strerror (ret));
     }
 
+  ca_status = get_ca_status ();
+  if (ca_status)
+    path_len = get_path_len ();
+  else
+    path_len = -1;
+
+  ret =
+       gnutls_x509_crq_set_basic_constraints (crq, ca_status, path_len);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "set_basic_constraints: %s", gnutls_strerror (ret));
+
+
+  ret = get_sign_status (1);
+  if (ret)
+    usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
+
+  ret = get_encrypt_status (1);
+  if (ret)
+    usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
+  else
+    usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
+
+  if (ca_status)
+    {
+         ret = get_cert_sign_status ();
+         if (ret)
+           usage |= GNUTLS_KEY_KEY_CERT_SIGN;
+
+         ret = get_crl_sign_status ();
+         if (ret)
+           usage |= GNUTLS_KEY_CRL_SIGN;
+    }
+
+  ret = gnutls_x509_crq_set_key_usage (crq, usage);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "key_usage: %s",
+                  gnutls_strerror (ret));
+
   ret = gnutls_x509_crq_set_key (crq, key);
   if (ret < 0)
     error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (ret));
index 623678405b984e255dd6778764b8b9b854b97b79..87def6d75eb25fbf0665a87b47c4a7b6345062e2 100644 (file)
@@ -9,32 +9,34 @@
 
 void certtool_version(void);
 
+#include "certtool-common.h"
+
 #}
 
 helpnode "Certtool help\nUsage: certtool [options]"
 
 #int privkey_op;
 #int action;
-option (s, generate-self-signed) { $action=0; } "Generate a self-signed certificate."
+option (s, generate-self-signed) { $action=ACTION_SELF_SIGNED; } "Generate a self-signed certificate."
 
-option (c, generate-certificate) { $action=4; } "Generate a signed certificate."
+option (c, generate-certificate) { $action=ACTION_GENERATE_CERTIFICATE; } "Generate a signed certificate."
 
-option (generate-proxy) { $action=17; } "Generate a proxy certificate."
+option (generate-proxy) { $action=ACTION_GENERATE_PROXY; } "Generate a proxy certificate."
 
-option (generate-crl) { $action=13; } "Generate a CRL."
+option (generate-crl) { $action=ACTION_GENERATE_CRL; } "Generate a CRL."
 
-option (u, update-certificate) { $action=7; } "Update a signed certificate."
+option (u, update-certificate) { $action=ACTION_UPDATE_CERTIFICATE; } "Update a signed certificate."
 
-option (p, generate-privkey) { $privkey_op=1; $action=1; } "Generate a private key."
+option (p, generate-privkey) { $privkey_op=1; $action=ACTION_GENERATE_PRIVKEY; } "Generate a private key."
 
-option (q, generate-request) { $action=3; } "Generate a PKCS #10 certificate request."
+option (q, generate-request) { $action=ACTION_GENERATE_REQUEST; } "Generate a PKCS #10 certificate request."
 
-option (e, verify-chain) { $action=5; } "Verify a PEM encoded certificate chain. The last certificate in the chain must be a self signed one."
+option (e, verify-chain) { $action=ACTION_VERIFY_CHAIN; } "Verify a PEM encoded certificate chain. The last certificate in the chain must be a self signed one."
 
-option (verify-crl) { $action=14; } "Verify a CRL."
+option (verify-crl) { $action=ACTION_VERIFY_CRL; } "Verify a CRL."
 
-option (generate-dh-params) { $action=10; } "Generate PKCS #3 encoded Diffie Hellman parameters."
-option (get-dh-params) { $action=16; } "Get the included PKCS #3 encoded Diffie Hellman parameters."
+option (generate-dh-params) { $action=ACTION_GENERATE_DH; } "Generate PKCS #3 encoded Diffie Hellman parameters."
+option (get-dh-params) { $action=ACTION_GET_DH; } "Get the included PKCS #3 encoded Diffie Hellman parameters."
 
 #char *privkey;
 option (load-privkey) STR "FILE" { $privkey = $1 } "Private key file to use."
@@ -54,25 +56,27 @@ option (load-ca-certificate) STR "FILE" { $ca = $1 } "Certificate authority's ce
 #char *pass;
 option (password) STR "PASSWORD" { $pass = $1 } "Password to use."
 
-option (i, certificate-info) { $action = 2; } "Print information on a certificate."
+option (i, certificate-info) { $action = ACTION_CERT_INFO; } "Print information on a certificate."
+
+option (pgp-certificate-info) { $action = ACTION_PGP_INFO; } "Print information on a OpenPGP certificate."
 
-option (pgp-certificate-info) { $action = 19; } "Print information on a OpenPGP certificate."
+option (pgp-ring-info) { $action = ACTION_RING_INFO; } "Print information on a keyring structure."
 
-option (pgp-ring-info) { $action = 21; } "Print information on a keyring structure."
+option (l, crl-info) { $action = ACTION_CRL_INFO; } "Print information on a CRL."
 
-option (l, crl-info) { $action = 11; } "Print information on a CRL."
+option (crq-info) { $action = ACTION_REQUEST; } "Print information on a Certificate Request."
 
-option (p12-info) { $action = 9; } "Print information on a PKCS #12 structure."
+option (p12-info) { $action = ACTION_PKCS12_INFO; } "Print information on a PKCS #12 structure."
 
-option (p7-info) { $action = 12; } "Print information on a PKCS #7 structure."
+option (p7-info) { $action = ACTION_P7_INFO; } "Print information on a PKCS #7 structure."
 
-option (smime-to-p7) { $action = 15; } "Convert S/MIME to PKCS #7 structure."
+option (smime-to-p7) { $action = ACTION_SMIME_TO_P7; } "Convert S/MIME to PKCS #7 structure."
 
 /* on private key operations set $privkey_op to != 0 
  */
-option (k, key-info) { $privkey_op=1; $action = 6; } "Print information on a private key."
+option (k, key-info) { $privkey_op=1; $action = ACTION_PRIVKEY_INFO; } "Print information on a private key."
 
-option (pgp-key-info) { $privkey_op=1; $action = 20; } "Print information on a OpenPGP private key."
+option (pgp-key-info) { $privkey_op=1; $action = ACTION_PGP_PRIVKEY_INFO; } "Print information on a OpenPGP private key."
 
 #int fix_key;
 option (fix-key) { $privkey_op=1; $fix_key = 1; } "Regenerate the parameters in a private key."
@@ -80,9 +84,9 @@ option (fix-key) { $privkey_op=1; $fix_key = 1; } "Regenerate the parameters in
 #int v1_cert;
 option (v1) { $v1_cert = 1; } "Generate an X.509 version 1 certificate (no extensions)."
 
-option (to-p12) { $action = 8; } "Generate a PKCS #12 structure."
+option (to-p12) { $action = ACTION_TO_PKCS12; } "Generate a PKCS #12 structure."
 
-option (to-p8) { $action = 18; } "Generate a PKCS #8 key structure."
+option (to-p8) { $action = ACTION_GENERATE_PKCS8; } "Generate a PKCS #8 key structure."
 
 #int pkcs8;
 option (8, pkcs8) { $pkcs8=1 } "Use PKCS #8 format for private keys."