emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] [emacs] 01/01: Export all certificate details to Lisp Land


From: Lars Ingebrigtsen
Subject: [Emacs-diffs] [emacs] 01/01: Export all certificate details to Lisp Land
Date: Tue, 18 Nov 2014 00:46:28 +0000

branch: nsm
commit 32566987c048705e6799a6a01882d125196ad265
Author: Lars Magne Ingebrigtsen <address@hidden>
Date:   Tue Nov 18 01:46:15 2014 +0100

    Export all certificate details to Lisp Land
    
    * gnutls.c (gnutls_certificate_details): New function.
---
 src/ChangeLog |    4 ++
 src/gnutls.c  |  152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 149 insertions(+), 7 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 4beee7b..b1244cd 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2014-11-18  Lars Magne Ingebrigtsen  <address@hidden>
+
+       * gnutls.c (gnutls_certificate_details): New function.
+
 2014-11-17  Lars Magne Ingebrigtsen  <address@hidden>
 
        * process.h: Add fields necessary for doing postponed gnutls peer
diff --git a/src/gnutls.c b/src/gnutls.c
index 25e244a..9d2338a 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -706,6 +706,140 @@ DEFUN ("gnutls-available-p", Fgnutls_available_p, 
Sgnutls_available_p, 0, 0, 0,
 #endif
 }
 
+
+Lisp_Object
+gnutls_certificate_details (gnutls_x509_crt_t cert)
+{
+  Lisp_Object res = Qnil;
+  int err;
+
+  /* Version. */
+  {
+    int version = gnutls_x509_crt_get_version (cert);
+    if (version >= GNUTLS_E_SUCCESS)
+      res = nconc2 (res, list2 (intern (":version"),
+                               make_number (version)));
+  }
+
+  /* Serial. */
+  {
+    unsigned char serial[128];
+    size_t serial_size = sizeof (serial);
+
+    err = gnutls_x509_crt_get_serial (cert, serial, &serial_size);
+    if (err >= GNUTLS_E_SUCCESS) {
+      Lisp_Object ser = make_uninit_string (serial_size * 3 - 1);
+      for (int i = 0; i < serial_size; i++)
+       sprintf (SDATA (ser) + i * 3,
+                i == serial_size - 1? "%02x": "%02x:",
+                serial[i]);
+      res = nconc2 (res, list2 (intern (":serial-number"), ser));
+    }
+  }
+
+  /* Issuer. */
+  {
+    size_t dn_size = 0;
+
+    err = gnutls_x509_crt_get_issuer_dn (cert, NULL, &dn_size);
+    if (err >= GNUTLS_E_SUCCESS) {
+      char *dn = malloc (dn_size);
+      err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size);
+      if (err >= GNUTLS_E_SUCCESS) {
+       res = nconc2 (res, list2 (intern (":issuer"),
+                                 make_string (dn, dn_size)));
+       free (dn);
+      }
+    }
+  }
+
+  /* Validity. */
+  {
+    time_t tim = gnutls_x509_crt_get_activation_time (cert);
+    res = nconc2 (res, list2 (intern (":valid-from"), make_number (tim)));
+
+    tim = gnutls_x509_crt_get_expiration_time (cert);
+    res = nconc2 (res, list2 (intern (":valid-to"), make_number (tim)));
+  }
+
+  /* Subject. */
+  {
+    size_t dn_size = 0;
+
+    err = gnutls_x509_crt_get_dn (cert, NULL, &dn_size);
+    if (err >= GNUTLS_E_SUCCESS) {
+      char *dn = malloc (dn_size);
+      err = gnutls_x509_crt_get_dn (cert, dn, &dn_size);
+      if (err >= GNUTLS_E_SUCCESS) {
+       res = nconc2 (res, list2 (intern (":subject"),
+                                 make_string (dn, dn_size)));
+       free (dn);
+      }
+    }
+  }
+
+  /* SubjectPublicKeyInfo. */
+  {
+    unsigned int bits;
+
+    err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
+    if (err >= GNUTLS_E_SUCCESS) {
+      const char *name = gnutls_pk_algorithm_get_name (err);
+      if (name)
+       res = nconc2 (res, list2 (intern (":public-key-algorithm"),
+                                 build_string (name)));
+
+      name = gnutls_sec_param_get_name (gnutls_pk_bits_to_sec_param
+                                       (err, bits));
+      res = nconc2 (res, list2 (intern (":certificate-security-level"),
+                               build_string (name)));
+    }
+  }
+
+  /* Unique IDs. */
+  {
+    char buf[256];                /* if its longer, we won't bother to print 
it */
+    size_t buf_size = 256;
+
+    err = gnutls_x509_crt_get_issuer_unique_id (cert, buf, &buf_size);
+    if (err >= GNUTLS_E_SUCCESS)
+      res = nconc2 (res, list2 (intern (":issuer-unique-id"),
+                               make_string (buf, buf_size)));
+
+    buf_size = 256;
+    err = gnutls_x509_crt_get_subject_unique_id (cert, buf, &buf_size);
+    if (err >= GNUTLS_E_SUCCESS)
+      res = nconc2 (res, list2 (intern (":subject-unique-id"),
+                               make_string (buf, buf_size)));
+  }
+
+  /* Signature. */
+  {
+    size_t buf_size = 0;
+
+    err = gnutls_x509_crt_get_signature_algorithm (cert);
+    if (err >= GNUTLS_E_SUCCESS) {
+      const char *name = gnutls_sign_algorithm_get_name (err);
+      if (name)
+       res = nconc2 (res, list2 (intern (":signature-algorithm"),
+                                 build_string (name)));
+
+      err = gnutls_x509_crt_get_signature (cert, NULL, &buf_size);
+      if (err >= GNUTLS_E_SUCCESS) {
+       char *buf = malloc (buf_size);
+       err = gnutls_x509_crt_get_signature (cert, buf, &buf_size);
+       if (err >= GNUTLS_E_SUCCESS) {
+         res = nconc2 (res, list2 (intern (":signature"),
+                                   make_string (buf, buf_size)));
+         free (buf);
+       }
+      }
+    }
+  }
+
+  return res;
+}
+
 DEFUN ("gnutls-peer-status", Fgnutls_peer_status, Sgnutls_peer_status, 1, 1, 0,
        doc: /* Return the status of the gnutls PROC peer certificate.
 The return value is a property list.  */)
@@ -714,7 +848,7 @@ The return value is a property list.  */)
   int ret;
   unsigned char buffer[GNUTLS_MAX_HASH_SIZE];
   size_t size = sizeof (buffer);
-  Lisp_Object hash, warnings = Qnil;
+  Lisp_Object hash, warnings = Qnil, result = Qnil;
   unsigned int verification;
 
   CHECK_PROCESS (proc);
@@ -781,13 +915,17 @@ The return value is a property list.  */)
                             build_string("certificate host does not match 
hostname")),
                      warnings);
 
-  if (NILP (warnings))
-    return list2 (intern (":fingerprint"), hash);
-  else
-    return list4 (intern (":fingerprint"), hash,
-                 intern (":warnings"), warnings);
-}
+  result = list2 (intern (":fingerprint"), hash);
+
+  if (!NILP (warnings))
+    result = nconc2 (result, list2 (intern (":warnings"), warnings));
 
+  result = nconc2 (result, list2
+                  (intern (":certificate"),
+                   gnutls_certificate_details(XPROCESS 
(proc)->gnutls_certificate)));
+
+  return result;
+}
 
 
 /* Initializes global GnuTLS state to defaults.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]