summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-06-09 19:07:58 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2015-06-24 17:26:36 +0200
commitcdee630f6f8fc170f21dbcc88248a18a466722a1 (patch)
tree6adb8c6adacc9a90408720248edc18e8b4ad43ba
parent8762d721f4cff582356a1591e220463c9ca1d389 (diff)
downloadlibgit2-cdee630f6f8fc170f21dbcc88248a18a466722a1.tar.gz
curl: extract certificate information
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.
-rw-r--r--include/git2/types.h12
-rw-r--r--src/curl_stream.c37
2 files changed, 46 insertions, 3 deletions
diff --git a/include/git2/types.h b/include/git2/types.h
index d1e7cd92c..c97e5ba61 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -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;
/**
diff --git a/src/curl_stream.c b/src/curl_stream.c
index 51b7fa7a4..906a67f2a 100644
--- a/src/curl_stream.c
+++ b/src/curl_stream.c
@@ -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);
}