]> git.proxmox.com Git - libgit2.git/commitdiff
curl: extract certificate information
authorCarlos Martín Nieto <cmn@dwim.me>
Tue, 9 Jun 2015 17:07:58 +0000 (19:07 +0200)
committerCarlos Martín Nieto <cmn@dwim.me>
Wed, 24 Jun 2015 15:26:36 +0000 (17:26 +0200)
The information is exposed by curl for some crypto libraries in the form
of name:content strings. We can't do much more than return this
information.

include/git2/types.h
src/curl_stream.c

index d1e7cd92c67f68f7f8942208dbf4f24f64e8f732..c97e5ba613a594d05de499ba530f486b2186fbb1 100644 (file)
@@ -284,6 +284,11 @@ typedef int (*git_transport_message_cb)(const char *str, int len, void *payload)
  * Type of host certificate structure that is passed to the check callback
  */
 typedef enum git_cert_t {
+       /**
+        * No information about the certificate is available. This may
+        * happen when using curl.
+        */
+       GIT_CERT_NONE,
         /**
          * The `data` argument to the callback will be a pointer to
          * the DER-encoded data.
@@ -294,6 +299,13 @@ typedef enum git_cert_t {
          * `git_cert_hostkey` structure.
          */
        GIT_CERT_HOSTKEY_LIBSSH2,
+       /**
+        * The `data` argument to the callback will be a pointer to a
+        * `git_strarray` with `name:content` strings containing
+        * information about the certificate. This is used when using
+        * curl.
+        */
+       GIT_CERT_STRARRAY,
 } git_cert_t;
 
 /**
index 51b7fa7a41f44e86d5547c03dddb4f43b518a85d..906a67f2ad6f532e4e02e6de74e2223610105ed0 100644 (file)
@@ -12,6 +12,7 @@
 #include "stream.h"
 #include "git2/transport.h"
 #include "buffer.h"
+#include "vector.h"
 
 typedef struct {
        git_stream parent;
@@ -19,6 +20,7 @@ typedef struct {
        curl_socket_t socket;
        char curl_error[CURL_ERROR_SIZE + 1];
        git_cert_x509 cert_info;
+       git_strarray cert_info_strings;
 } curl_stream;
 
 static int seterr_curl(curl_stream *s)
@@ -53,11 +55,39 @@ static int curls_connect(git_stream *stream)
 
 static int curls_certificate(git_cert **out, git_stream *stream)
 {
+       int error;
+       CURLcode res;
+       struct curl_slist *slist;
+       struct curl_certinfo *certinfo;
+       git_vector strings = GIT_VECTOR_INIT;
        curl_stream *s = (curl_stream *) stream;
 
-       s->cert_info.cert_type = GIT_CERT_X509;
-       s->cert_info.data      = NULL;
-       s->cert_info.len       = 0;
+       if ((res = curl_easy_getinfo(s->handle, CURLINFO_CERTINFO, &certinfo)) != CURLE_OK)
+               return seterr_curl(s);
+
+       /* No information is available, can happen with SecureTransport */
+       if (certinfo->num_of_certs == 0) {
+               s->cert_info.cert_type = GIT_CERT_NONE;
+               s->cert_info.data      = NULL;
+               s->cert_info.len       = 0;
+               return 0;
+       }
+
+       if ((error = git_vector_init(&strings, 8, NULL)) < 0)
+               return error;
+
+       for (slist = certinfo->certinfo[0]; slist; slist = slist->next) {
+               char *str = git__strdup(slist->data);
+               GITERR_CHECK_ALLOC(str);
+       }
+
+       /* Copy the contents of the vector into a strarray so we can expose them */
+       s->cert_info_strings.strings = (char **) strings.contents;
+       s->cert_info_strings.count   = strings.length;
+
+       s->cert_info.cert_type = GIT_CERT_STRARRAY;
+       s->cert_info.data      = &s->cert_info_strings;
+       s->cert_info.len       = strings.length;
 
        *out = (git_cert *) &s->cert_info;
 
@@ -161,6 +191,7 @@ static void curls_free(git_stream *stream)
        curl_stream *s = (curl_stream *) stream;
 
        curls_close(stream);
+       git_strarray_free(&s->cert_info_strings);
        git__free(s);
 }