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

Bug#703932: apt-transport-https not sending a certificate to the server



On Tue, Mar 26, 2013 at 09:22:28AM +0100, Holger Hans Peter Freyther wrote:
> On Tue, Mar 26, 2013 at 06:46:15AM +0100, Michael Vogt wrote:
[..]
> > Can you please run with Debug enabled?
> > $ sudo apt-get update -o Debug::Acquire::https=1
> 
> I have the debug output already in a .conf.d file (as indicated in the original
> mail).
> 
> > and see what that prints?

Ups, sorry, I overlooked that.
 
> * About to connect() to HOST port PORT (#0)
> *   Trying IP...
> * Connected to HOST (IP) port PORT (#0)
> * found 1 certificates in /home/ich/cert/ca.crt
> * gnutls_handshake() failed: Handshake failed
> * Closing connection 0
> 
> that is really all. 

Hm, that is really not that much. You can try the attached patch and
rebuild apt with that - that should give you much more debug
output. If that is not helpful some more ideas below.

> Until yesterday the first hit on google for this
> issue was[1]. I don't see a resolution in this thread though.
> 
> One of the issues with the code is the lack of checking return values:
> 
> methods/https.cc
>    string key = _config->Find("Acquire::https::SslKey","");
>    knob = "Acquire::https::"+remotehost+"::SslKey";
>    key = _config->Find(knob.c_str(),key.c_str());
>    if(key.empty() == false)
>       curl_easy_setopt(curl, CURLOPT_SSLKEY, key.c_str());
> 
> curl_easy_setopt returns a a CURLcode, this is not checked in the
> above code. So it might be (probably not) that curl already informs the caller
> that there is something wrong with the key.

Yeah, this should be fixed to actually check the return code. 

Looking at the error "Handshake failed" error that is mapped
internally in gnutls in gnutls_alert.c it seems that could be any of
the following:
"""
case GNUTLS_E_UNKNOWN_CIPHER_SUITE:
    case GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM:
    case GNUTLS_E_INSUFFICIENT_CREDENTIALS:
    case GNUTLS_E_NO_CIPHER_SUITES:
    case GNUTLS_E_NO_COMPRESSION_ALGORITHMS:
    case GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM:
    case GNUTLS_E_SAFE_RENEGOTIATION_FAILED:
    case GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL:
      ret = GNUTLS_A_HANDSHAKE_FAILURE;
      _level = GNUTLS_AL_FATAL;
      break;
"""
But that is of course not very helpful. You mentioned that the
gnutls-cli commandline works for you? Could you please provide the
commandline you used? 

Cheers,
 Michael
=== modified file 'methods/https.cc'
--- methods/https.cc	2012-05-17 12:21:13 +0000
+++ methods/https.cc	2013-03-26 13:33:22 +0000
@@ -30,12 +30,19 @@
 #include <iostream>
 #include <sstream>
 
+#include <gnutls/gnutls.h>
+
 #include "config.h"
 #include "https.h"
 #include <apti18n.h>
 									/*}}}*/
 using namespace std;
 
+static void tls_log_func(int level, const char *str)
+{
+    fprintf(stderr, "|<%d>| %s", level, str);
+}
+
 size_t 
 HttpsMethod::write_data(void *buffer, size_t size, size_t nmemb, void *userp)
 {
@@ -237,8 +244,14 @@
 
    // debug
    if(_config->FindB("Debug::Acquire::https", false))
+   {
       curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
 
+      gnutls_global_set_log_function(tls_log_func);
+      gnutls_global_set_log_level(
+         _config->FindI("Debug::Acquire::gnutls-level", 3));
+   }
+
    // error handling
    curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errorstr);
 


Reply to: