~ubuntu-branches/ubuntu/precise/wget/precise-proposed

« back to all changes in this revision

Viewing changes to .pc/disable-SSLv2/src/openssl.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2011-10-19 00:00:09 UTC
  • mfrom: (2.1.13 sid)
  • Revision ID: james.westby@ubuntu.com-20111019000009-8p33w3wz4b1rdri0
Tags: 1.13-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add wget-udeb to ship wget.gnu as alternative to busybox wget
    implementation.
  - Depend on libssl-dev 0.9.8k-7ubuntu4 (LP: #503339)
* Dropped changes, superseded in Debian:
  - Keep build dependencies in main:
    + debian/control: remove info2man build-dep
    + debian/patches/series: disable wget-infopod_generated_manpage
  - Mark wget Multi-Arch: foreign, so packages that aren't of the same arch
    can depend on it.
* Pass --with-ssl=openssl; we don't want to use gnutls, there's no udeb for
  it.
* Add a second build pass for the udeb, so we can build without libidn.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* SSL support via OpenSSL library.
2
 
   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3
 
   2009 Free Software Foundation, Inc.
4
 
   Originally contributed by Christian Fraenkel.
5
 
 
6
 
This file is part of GNU Wget.
7
 
 
8
 
GNU Wget is free software; you can redistribute it and/or modify
9
 
it under the terms of the GNU General Public License as published by
10
 
the Free Software Foundation; either version 3 of the License, or
11
 
(at your option) any later version.
12
 
 
13
 
GNU Wget is distributed in the hope that it will be useful,
14
 
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
GNU General Public License for more details.
17
 
 
18
 
You should have received a copy of the GNU General Public License
19
 
along with Wget.  If not, see <http://www.gnu.org/licenses/>.
20
 
 
21
 
Additional permission under GNU GPL version 3 section 7
22
 
 
23
 
If you modify this program, or any covered work, by linking or
24
 
combining it with the OpenSSL project's OpenSSL library (or a
25
 
modified version of that library), containing parts covered by the
26
 
terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
27
 
grants you additional permission to convey the resulting work.
28
 
Corresponding Source for a non-source form of such a combination
29
 
shall include the source code for the parts of OpenSSL used as well
30
 
as that of the covered work.  */
31
 
 
32
 
#include "wget.h"
33
 
 
34
 
#include <assert.h>
35
 
#include <errno.h>
36
 
#ifdef HAVE_UNISTD_H
37
 
# include <unistd.h>
38
 
#endif
39
 
#include <string.h>
40
 
 
41
 
#include <openssl/ssl.h>
42
 
#include <openssl/x509.h>
43
 
#include <openssl/err.h>
44
 
#include <openssl/rand.h>
45
 
 
46
 
#include "utils.h"
47
 
#include "connect.h"
48
 
#include "url.h"
49
 
#include "ssl.h"
50
 
 
51
 
/* Application-wide SSL context.  This is common to all SSL
52
 
   connections.  */
53
 
static SSL_CTX *ssl_ctx;
54
 
 
55
 
/* Initialize the SSL's PRNG using various methods. */
56
 
 
57
 
static void
58
 
init_prng (void)
59
 
{
60
 
  char namebuf[256];
61
 
  const char *random_file;
62
 
 
63
 
  if (RAND_status ())
64
 
    /* The PRNG has been seeded; no further action is necessary. */
65
 
    return;
66
 
 
67
 
  /* Seed from a file specified by the user.  This will be the file
68
 
     specified with --random-file, $RANDFILE, if set, or ~/.rnd, if it
69
 
     exists.  */
70
 
  if (opt.random_file)
71
 
    random_file = opt.random_file;
72
 
  else
73
 
    {
74
 
      /* Get the random file name using RAND_file_name. */
75
 
      namebuf[0] = '\0';
76
 
      random_file = RAND_file_name (namebuf, sizeof (namebuf));
77
 
    }
78
 
 
79
 
  if (random_file && *random_file)
80
 
    /* Seed at most 16k (apparently arbitrary value borrowed from
81
 
       curl) from random file. */
82
 
    RAND_load_file (random_file, 16384);
83
 
 
84
 
  if (RAND_status ())
85
 
    return;
86
 
 
87
 
  /* Get random data from EGD if opt.egd_file was used.  */
88
 
  if (opt.egd_file && *opt.egd_file)
89
 
    RAND_egd (opt.egd_file);
90
 
 
91
 
  if (RAND_status ())
92
 
    return;
93
 
 
94
 
#ifdef WINDOWS
95
 
  /* Under Windows, we can try to seed the PRNG using screen content.
96
 
     This may or may not work, depending on whether we'll calling Wget
97
 
     interactively.  */
98
 
 
99
 
  RAND_screen ();
100
 
  if (RAND_status ())
101
 
    return;
102
 
#endif
103
 
 
104
 
#if 0 /* don't do this by default */
105
 
  {
106
 
    int maxrand = 500;
107
 
 
108
 
    /* Still not random enough, presumably because neither /dev/random
109
 
       nor EGD were available.  Try to seed OpenSSL's PRNG with libc
110
 
       PRNG.  This is cryptographically weak and defeats the purpose
111
 
       of using OpenSSL, which is why it is highly discouraged.  */
112
 
 
113
 
    logprintf (LOG_NOTQUIET, _("WARNING: using a weak random seed.\n"));
114
 
 
115
 
    while (RAND_status () == 0 && maxrand-- > 0)
116
 
      {
117
 
        unsigned char rnd = random_number (256);
118
 
        RAND_seed (&rnd, sizeof (rnd));
119
 
      }
120
 
  }
121
 
#endif
122
 
}
123
 
 
124
 
/* Print errors in the OpenSSL error stack. */
125
 
 
126
 
static void
127
 
print_errors (void)
128
 
{
129
 
  unsigned long err;
130
 
  while ((err = ERR_get_error ()) != 0)
131
 
    logprintf (LOG_NOTQUIET, "OpenSSL: %s\n", ERR_error_string (err, NULL));
132
 
}
133
 
 
134
 
/* Convert keyfile type as used by options.h to a type as accepted by
135
 
   SSL_CTX_use_certificate_file and SSL_CTX_use_PrivateKey_file.
136
 
 
137
 
   (options.h intentionally doesn't use values from openssl/ssl.h so
138
 
   it doesn't depend specifically on OpenSSL for SSL functionality.)  */
139
 
 
140
 
static int
141
 
key_type_to_ssl_type (enum keyfile_type type)
142
 
{
143
 
  switch (type)
144
 
    {
145
 
    case keyfile_pem:
146
 
      return SSL_FILETYPE_PEM;
147
 
    case keyfile_asn1:
148
 
      return SSL_FILETYPE_ASN1;
149
 
    default:
150
 
      abort ();
151
 
    }
152
 
}
153
 
 
154
 
/* Create an SSL Context and set default paths etc.  Called the first
155
 
   time an HTTP download is attempted.
156
 
 
157
 
   Returns true on success, false otherwise.  */
158
 
 
159
 
bool
160
 
ssl_init ()
161
 
{
162
 
  SSL_METHOD *meth;
163
 
 
164
 
  if (ssl_ctx)
165
 
    /* The SSL has already been initialized. */
166
 
    return true;
167
 
 
168
 
  /* Init the PRNG.  If that fails, bail out.  */
169
 
  init_prng ();
170
 
  if (RAND_status () != 1)
171
 
    {
172
 
      logprintf (LOG_NOTQUIET,
173
 
                 _("Could not seed PRNG; consider using --random-file.\n"));
174
 
      goto error;
175
 
    }
176
 
 
177
 
  SSL_library_init ();
178
 
  SSL_load_error_strings ();
179
 
  SSLeay_add_all_algorithms ();
180
 
  SSLeay_add_ssl_algorithms ();
181
 
 
182
 
  switch (opt.secure_protocol)
183
 
    {
184
 
    case secure_protocol_auto:
185
 
      meth = SSLv23_client_method ();
186
 
      break;
187
 
    case secure_protocol_sslv2:
188
 
      meth = SSLv2_client_method ();
189
 
      break;
190
 
    case secure_protocol_sslv3:
191
 
      meth = SSLv3_client_method ();
192
 
      break;
193
 
    case secure_protocol_tlsv1:
194
 
      meth = TLSv1_client_method ();
195
 
      break;
196
 
    default:
197
 
      abort ();
198
 
    }
199
 
 
200
 
  ssl_ctx = SSL_CTX_new (meth);
201
 
  if (!ssl_ctx)
202
 
    goto error;
203
 
 
204
 
  SSL_CTX_set_default_verify_paths (ssl_ctx);
205
 
  SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory);
206
 
 
207
 
  /* SSL_VERIFY_NONE instructs OpenSSL not to abort SSL_connect if the
208
 
     certificate is invalid.  We verify the certificate separately in
209
 
     ssl_check_certificate, which provides much better diagnostics
210
 
     than examining the error stack after a failed SSL_connect.  */
211
 
  SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL);
212
 
 
213
 
  /* Use the private key from the cert file unless otherwise specified. */
214
 
  if (opt.cert_file && !opt.private_key)
215
 
    {
216
 
      opt.private_key = opt.cert_file;
217
 
      opt.private_key_type = opt.cert_type;
218
 
    }
219
 
 
220
 
  if (opt.cert_file)
221
 
    if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
222
 
                                      key_type_to_ssl_type (opt.cert_type))
223
 
        != 1)
224
 
      goto error;
225
 
  if (opt.private_key)
226
 
    if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key,
227
 
                                     key_type_to_ssl_type (opt.private_key_type))
228
 
        != 1)
229
 
      goto error;
230
 
 
231
 
  /* Since fd_write unconditionally assumes partial writes (and
232
 
     handles them correctly), allow them in OpenSSL.  */
233
 
  SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
234
 
 
235
 
  /* The OpenSSL library can handle renegotiations automatically, so
236
 
     tell it to do so.  */
237
 
  SSL_CTX_set_mode (ssl_ctx, SSL_MODE_AUTO_RETRY);
238
 
 
239
 
  return true;
240
 
 
241
 
 error:
242
 
  if (ssl_ctx)
243
 
    SSL_CTX_free (ssl_ctx);
244
 
  print_errors ();
245
 
  return false;
246
 
}
247
 
 
248
 
struct openssl_transport_context {
249
 
  SSL *conn;                    /* SSL connection handle */
250
 
  char *last_error;             /* last error printed with openssl_errstr */
251
 
};
252
 
 
253
 
static int
254
 
openssl_read (int fd, char *buf, int bufsize, void *arg)
255
 
{
256
 
  int ret;
257
 
  struct openssl_transport_context *ctx = arg;
258
 
  SSL *conn = ctx->conn;
259
 
  do
260
 
    ret = SSL_read (conn, buf, bufsize);
261
 
  while (ret == -1
262
 
         && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
263
 
         && errno == EINTR);
264
 
  return ret;
265
 
}
266
 
 
267
 
static int
268
 
openssl_write (int fd, char *buf, int bufsize, void *arg)
269
 
{
270
 
  int ret = 0;
271
 
  struct openssl_transport_context *ctx = arg;
272
 
  SSL *conn = ctx->conn;
273
 
  do
274
 
    ret = SSL_write (conn, buf, bufsize);
275
 
  while (ret == -1
276
 
         && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
277
 
         && errno == EINTR);
278
 
  return ret;
279
 
}
280
 
 
281
 
static int
282
 
openssl_poll (int fd, double timeout, int wait_for, void *arg)
283
 
{
284
 
  struct openssl_transport_context *ctx = arg;
285
 
  SSL *conn = ctx->conn;
286
 
  if (timeout == 0)
287
 
    return 1;
288
 
  if (SSL_pending (conn))
289
 
    return 1;
290
 
  return select_fd (fd, timeout, wait_for);
291
 
}
292
 
 
293
 
static int
294
 
openssl_peek (int fd, char *buf, int bufsize, void *arg)
295
 
{
296
 
  int ret;
297
 
  struct openssl_transport_context *ctx = arg;
298
 
  SSL *conn = ctx->conn;
299
 
  do
300
 
    ret = SSL_peek (conn, buf, bufsize);
301
 
  while (ret == -1
302
 
         && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
303
 
         && errno == EINTR);
304
 
  return ret;
305
 
}
306
 
 
307
 
static const char *
308
 
openssl_errstr (int fd, void *arg)
309
 
{
310
 
  struct openssl_transport_context *ctx = arg;
311
 
  unsigned long errcode;
312
 
  char *errmsg = NULL;
313
 
  int msglen = 0;
314
 
 
315
 
  /* If there are no SSL-specific errors, just return NULL. */
316
 
  if ((errcode = ERR_get_error ()) == 0)
317
 
    return NULL;
318
 
 
319
 
  /* Get rid of previous contents of ctx->last_error, if any.  */
320
 
  xfree_null (ctx->last_error);
321
 
 
322
 
  /* Iterate over OpenSSL's error stack and accumulate errors in the
323
 
     last_error buffer, separated by "; ".  This is better than using
324
 
     a static buffer, which *always* takes up space (and has to be
325
 
     large, to fit more than one error message), whereas these
326
 
     allocations are only performed when there is an actual error.  */
327
 
 
328
 
  for (;;)
329
 
    {
330
 
      const char *str = ERR_error_string (errcode, NULL);
331
 
      int len = strlen (str);
332
 
 
333
 
      /* Allocate space for the existing message, plus two more chars
334
 
         for the "; " separator and one for the terminating \0.  */
335
 
      errmsg = xrealloc (errmsg, msglen + len + 2 + 1);
336
 
      memcpy (errmsg + msglen, str, len);
337
 
      msglen += len;
338
 
 
339
 
      /* Get next error and bail out if there are no more. */
340
 
      errcode = ERR_get_error ();
341
 
      if (errcode == 0)
342
 
        break;
343
 
 
344
 
      errmsg[msglen++] = ';';
345
 
      errmsg[msglen++] = ' ';
346
 
    }
347
 
  errmsg[msglen] = '\0';
348
 
 
349
 
  /* Store the error in ctx->last_error where openssl_close will
350
 
     eventually find it and free it.  */
351
 
  ctx->last_error = errmsg;
352
 
 
353
 
  return errmsg;
354
 
}
355
 
 
356
 
static void
357
 
openssl_close (int fd, void *arg)
358
 
{
359
 
  struct openssl_transport_context *ctx = arg;
360
 
  SSL *conn = ctx->conn;
361
 
 
362
 
  SSL_shutdown (conn);
363
 
  SSL_free (conn);
364
 
  xfree_null (ctx->last_error);
365
 
  xfree (ctx);
366
 
 
367
 
#if defined(WINDOWS) || defined(USE_WATT32)
368
 
  closesocket (fd);
369
 
#else
370
 
  close (fd);
371
 
#endif
372
 
 
373
 
  DEBUGP (("Closed %d/SSL 0x%0*lx\n", fd, PTR_FORMAT (conn)));
374
 
}
375
 
 
376
 
/* openssl_transport is the singleton that describes the SSL transport
377
 
   methods provided by this file.  */
378
 
 
379
 
static struct transport_implementation openssl_transport = {
380
 
  openssl_read, openssl_write, openssl_poll,
381
 
  openssl_peek, openssl_errstr, openssl_close
382
 
};
383
 
 
384
 
/* Perform the SSL handshake on file descriptor FD, which is assumed
385
 
   to be connected to an SSL server.  The SSL handle provided by
386
 
   OpenSSL is registered with the file descriptor FD using
387
 
   fd_register_transport, so that subsequent calls to fd_read,
388
 
   fd_write, etc., will use the corresponding SSL functions.
389
 
 
390
 
   Returns true on success, false on failure.  */
391
 
 
392
 
bool
393
 
ssl_connect_wget (int fd)
394
 
{
395
 
  SSL *conn;
396
 
  struct openssl_transport_context *ctx;
397
 
 
398
 
  DEBUGP (("Initiating SSL handshake.\n"));
399
 
 
400
 
  assert (ssl_ctx != NULL);
401
 
  conn = SSL_new (ssl_ctx);
402
 
  if (!conn)
403
 
    goto error;
404
 
  if (!SSL_set_fd (conn, fd))
405
 
    goto error;
406
 
  SSL_set_connect_state (conn);
407
 
  if (SSL_connect (conn) <= 0 || conn->state != SSL_ST_OK)
408
 
    goto error;
409
 
 
410
 
  ctx = xnew0 (struct openssl_transport_context);
411
 
  ctx->conn = conn;
412
 
 
413
 
  /* Register FD with Wget's transport layer, i.e. arrange that our
414
 
     functions are used for reading, writing, and polling.  */
415
 
  fd_register_transport (fd, &openssl_transport, ctx);
416
 
  DEBUGP (("Handshake successful; connected socket %d to SSL handle 0x%0*lx\n",
417
 
           fd, PTR_FORMAT (conn)));
418
 
  return true;
419
 
 
420
 
 error:
421
 
  DEBUGP (("SSL handshake failed.\n"));
422
 
  print_errors ();
423
 
  if (conn)
424
 
    SSL_free (conn);
425
 
  return false;
426
 
}
427
 
 
428
 
#define ASTERISK_EXCLUDES_DOT   /* mandated by rfc2818 */
429
 
 
430
 
/* Return true is STRING (case-insensitively) matches PATTERN, false
431
 
   otherwise.  The recognized wildcard character is "*", which matches
432
 
   any character in STRING except ".".  Any number of the "*" wildcard
433
 
   may be present in the pattern.
434
 
 
435
 
   This is used to match of hosts as indicated in rfc2818: "Names may
436
 
   contain the wildcard character * which is considered to match any
437
 
   single domain name component or component fragment. E.g., *.a.com
438
 
   matches foo.a.com but not bar.foo.a.com. f*.com matches foo.com but
439
 
   not bar.com [or foo.bar.com]."
440
 
 
441
 
   If the pattern contain no wildcards, pattern_match(a, b) is
442
 
   equivalent to !strcasecmp(a, b).  */
443
 
 
444
 
static bool
445
 
pattern_match (const char *pattern, const char *string)
446
 
{
447
 
  const char *p = pattern, *n = string;
448
 
  char c;
449
 
  for (; (c = c_tolower (*p++)) != '\0'; n++)
450
 
    if (c == '*')
451
 
      {
452
 
        for (c = c_tolower (*p); c == '*'; c = c_tolower (*++p))
453
 
          ;
454
 
        for (; *n != '\0'; n++)
455
 
          if (c_tolower (*n) == c && pattern_match (p, n))
456
 
            return true;
457
 
#ifdef ASTERISK_EXCLUDES_DOT
458
 
          else if (*n == '.')
459
 
            return false;
460
 
#endif
461
 
        return c == '\0';
462
 
      }
463
 
    else
464
 
      {
465
 
        if (c != c_tolower (*n))
466
 
          return false;
467
 
      }
468
 
  return *n == '\0';
469
 
}
470
 
 
471
 
/* Verify the validity of the certificate presented by the server.
472
 
   Also check that the "common name" of the server, as presented by
473
 
   its certificate, corresponds to HOST.  (HOST typically comes from
474
 
   the URL and is what the user thinks he's connecting to.)
475
 
 
476
 
   This assumes that ssl_connect_wget has successfully finished, i.e. that
477
 
   the SSL handshake has been performed and that FD is connected to an
478
 
   SSL handle.
479
 
 
480
 
   If opt.check_cert is true (the default), this returns 1 if the
481
 
   certificate is valid, 0 otherwise.  If opt.check_cert is 0, the
482
 
   function always returns 1, but should still be called because it
483
 
   warns the user about any problems with the certificate.  */
484
 
 
485
 
bool
486
 
ssl_check_certificate (int fd, const char *host)
487
 
{
488
 
  X509 *cert;
489
 
  char common_name[256];
490
 
  long vresult;
491
 
  bool success = true;
492
 
 
493
 
  /* If the user has specified --no-check-cert, we still want to warn
494
 
     him about problems with the server's certificate.  */
495
 
  const char *severity = opt.check_cert ? _("ERROR") : _("WARNING");
496
 
 
497
 
  struct openssl_transport_context *ctx = fd_transport_context (fd);
498
 
  SSL *conn = ctx->conn;
499
 
  assert (conn != NULL);
500
 
 
501
 
  cert = SSL_get_peer_certificate (conn);
502
 
  if (!cert)
503
 
    {
504
 
      logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"),
505
 
                 severity, quotearg_style (escape_quoting_style, host));
506
 
      success = false;
507
 
      goto no_cert;             /* must bail out since CERT is NULL */
508
 
    }
509
 
 
510
 
  IF_DEBUG
511
 
    {
512
 
      char *subject = X509_NAME_oneline (X509_get_subject_name (cert), 0, 0);
513
 
      char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
514
 
      DEBUGP (("certificate:\n  subject: %s\n  issuer:  %s\n",
515
 
               quotearg_n_style (0, escape_quoting_style, subject),
516
 
               quotearg_n_style (1, escape_quoting_style, issuer)));
517
 
      OPENSSL_free (subject);
518
 
      OPENSSL_free (issuer);
519
 
    }
520
 
 
521
 
  vresult = SSL_get_verify_result (conn);
522
 
  if (vresult != X509_V_OK)
523
 
    {
524
 
      char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
525
 
      logprintf (LOG_NOTQUIET,
526
 
                 _("%s: cannot verify %s's certificate, issued by %s:\n"),
527
 
                 severity, quotearg_n_style (0, escape_quoting_style, host),
528
 
                 quote_n (1, issuer));
529
 
      /* Try to print more user-friendly (and translated) messages for
530
 
         the frequent verification errors.  */
531
 
      switch (vresult)
532
 
        {
533
 
        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
534
 
          logprintf (LOG_NOTQUIET,
535
 
                     _("  Unable to locally verify the issuer's authority.\n"));
536
 
          break;
537
 
        case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
538
 
        case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
539
 
          logprintf (LOG_NOTQUIET, _("  Self-signed certificate encountered.\n"));
540
 
          break;
541
 
        case X509_V_ERR_CERT_NOT_YET_VALID:
542
 
          logprintf (LOG_NOTQUIET, _("  Issued certificate not yet valid.\n"));
543
 
          break;
544
 
        case X509_V_ERR_CERT_HAS_EXPIRED:
545
 
          logprintf (LOG_NOTQUIET, _("  Issued certificate has expired.\n"));
546
 
          break;
547
 
        default:
548
 
          /* For the less frequent error strings, simply provide the
549
 
             OpenSSL error message.  */
550
 
          logprintf (LOG_NOTQUIET, "  %s\n",
551
 
                     X509_verify_cert_error_string (vresult));
552
 
        }
553
 
      success = false;
554
 
      /* Fall through, so that the user is warned about *all* issues
555
 
         with the cert (important with --no-check-certificate.)  */
556
 
    }
557
 
 
558
 
  /* Check that HOST matches the common name in the certificate.
559
 
     #### The following remains to be done:
560
 
 
561
 
     - It should use dNSName/ipAddress subjectAltName extensions if
562
 
       available; according to rfc2818: "If a subjectAltName extension
563
 
       of type dNSName is present, that MUST be used as the identity."
564
 
 
565
 
     - When matching against common names, it should loop over all
566
 
       common names and choose the most specific one, i.e. the last
567
 
       one, not the first one, which the current code picks.
568
 
 
569
 
     - Ensure that ASN1 strings from the certificate are encoded as
570
 
       UTF-8 which can be meaningfully compared to HOST.  */
571
 
 
572
 
  X509_NAME *xname = X509_get_subject_name(cert);
573
 
  common_name[0] = '\0';
574
 
  X509_NAME_get_text_by_NID (xname, NID_commonName, common_name,
575
 
                             sizeof (common_name));
576
 
 
577
 
  if (!pattern_match (common_name, host))
578
 
    {
579
 
      logprintf (LOG_NOTQUIET, _("\
580
 
%s: certificate common name %s doesn't match requested host name %s.\n"),
581
 
                 severity, quote_n (0, common_name), quote_n (1, host));
582
 
      success = false;
583
 
    }
584
 
  else
585
 
    {
586
 
      /* We now determine the length of the ASN1 string. If it differs from
587
 
       * common_name's length, then there is a \0 before the string terminates.
588
 
       * This can be an instance of a null-prefix attack.
589
 
       *
590
 
       * https://www.blackhat.com/html/bh-usa-09/bh-usa-09-archives.html#Marlinspike
591
 
       * */
592
 
 
593
 
      int i = -1, j;
594
 
      X509_NAME_ENTRY *xentry;
595
 
      ASN1_STRING *sdata;
596
 
 
597
 
      if (xname) {
598
 
        for (;;)
599
 
          {
600
 
            j = X509_NAME_get_index_by_NID (xname, NID_commonName, i);
601
 
            if (j == -1) break;
602
 
            i = j;
603
 
          }
604
 
      }
605
 
 
606
 
      xentry = X509_NAME_get_entry(xname,i);
607
 
      sdata = X509_NAME_ENTRY_get_data(xentry);
608
 
      if (strlen (common_name) != ASN1_STRING_length (sdata))
609
 
        {
610
 
          logprintf (LOG_NOTQUIET, _("\
611
 
%s: certificate common name is invalid (contains a NUL character).\n\
612
 
This may be an indication that the host is not who it claims to be\n\
613
 
(that is, it is not the real %s).\n"),
614
 
                     severity, quote (host));
615
 
          success = false;
616
 
        }
617
 
    }
618
 
 
619
 
 
620
 
  if (success)
621
 
    DEBUGP (("X509 certificate successfully verified and matches host %s\n",
622
 
             quotearg_style (escape_quoting_style, host)));
623
 
  X509_free (cert);
624
 
 
625
 
 no_cert:
626
 
  if (opt.check_cert && !success)
627
 
    logprintf (LOG_NOTQUIET, _("\
628
 
To connect to %s insecurely, use `--no-check-certificate'.\n"),
629
 
               quotearg_style (escape_quoting_style, host));
630
 
 
631
 
  /* Allow --no-check-cert to disable certificate checking. */
632
 
  return opt.check_cert ? success : true;
633
 
}