diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2015-06-09 19:07:58 +0200 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2015-06-24 17:26:36 +0200 |
commit | cdee630f6f8fc170f21dbcc88248a18a466722a1 (patch) | |
tree | 6adb8c6adacc9a90408720248edc18e8b4ad43ba | |
parent | 8762d721f4cff582356a1591e220463c9ca1d389 (diff) | |
download | libgit2-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.h | 12 | ||||
-rw-r--r-- | src/curl_stream.c | 37 |
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); } |