~ubuntu-branches/ubuntu/vivid/curl/vivid

« back to all changes in this revision

Viewing changes to lib/sslgen.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Schuldei
  • Date: 2009-04-02 23:35:45 UTC
  • mto: (1.2.1 upstream) (3.2.3 sid)
  • mto: This revision was merged to the branch mainline in revision 38.
  • Revision ID: james.westby@ubuntu.com-20090402233545-geixkwhe3izccjt7
Tags: upstream-7.19.4
ImportĀ upstreamĀ versionĀ 7.19.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *                            | (__| |_| |  _ <| |___
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
 
8
 * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
9
9
 *
10
10
 * This software is licensed as described in the file COPYING, which
11
11
 * you should have received as part of this distribution. The terms
18
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
19
 * KIND, either express or implied.
20
20
 *
21
 
 * $Id: sslgen.c,v 1.37 2008-05-09 11:27:55 mmarek Exp $
 
21
 * $Id: sslgen.c,v 1.45 2009-02-25 12:51:39 bagder Exp $
22
22
 ***************************************************************************/
23
23
 
24
 
/* This file is for "generic" SSL functions that all libcurl internals should
25
 
   use. It is responsible for calling the proper 'ossl' function in ssluse.c
26
 
   (OpenSSL based) or the 'gtls' function in gtls.c (GnuTLS based).
 
24
/* This file is for implementing all "generic" SSL functions that all libcurl
 
25
   internals should use. It is then responsible for calling the proper
 
26
   "backend" function.
27
27
 
28
28
   SSL-functions in libcurl should call functions in this source file, and not
29
29
   to any specific SSL-layer.
33
33
   Curl_gtls_ - prefix for GnuTLS ones
34
34
   Curl_nss_ - prefix for NSS ones
35
35
 
 
36
   Note that this source code uses curlssl_* functions, and they are all
 
37
   defines/macros #defined by the lib-specific header files.
 
38
 
36
39
   "SSL/TLS Strong Encryption: An Introduction"
37
40
   http://httpd.apache.org/docs-2.0/ssl/ssl_intro.html
38
41
*/
54
57
#include "nssg.h"   /* NSS versions */
55
58
#include "qssl.h"   /* QSOSSL versions */
56
59
#include "sendf.h"
57
 
#include "strequal.h"
 
60
#include "rawstr.h"
58
61
#include "url.h"
59
62
#include "memory.h"
 
63
#include "progress.h"
60
64
/* The last #include file should be: */
61
65
#include "memdebug.h"
62
66
 
63
 
/* "global" init done? */
64
 
static bool init_ssl=FALSE;
65
 
 
66
 
static bool safe_strequal(char* str1, char* str2);
67
 
 
68
67
static bool safe_strequal(char* str1, char* str2)
69
68
{
70
69
  if(str1 && str2)
71
70
    /* both pointers point to something then compare them */
72
 
    return (bool)(0 != strequal(str1, str2));
 
71
    return (bool)(0 != Curl_raw_equal(str1, str2));
73
72
  else
74
73
    /* if both pointers are NULL then treat them as equal */
75
74
    return (bool)(!str1 && !str2);
143
142
  Curl_safefree(sslc->random_file);
144
143
}
145
144
 
 
145
#ifdef USE_SSL
 
146
 
 
147
/* "global" init done? */
 
148
static bool init_ssl=FALSE;
 
149
 
146
150
/**
147
151
 * Global SSL init
148
152
 *
156
160
    return 1;
157
161
  init_ssl = TRUE; /* never again */
158
162
 
159
 
#ifdef USE_SSLEAY
160
 
  return Curl_ossl_init();
161
 
#else
162
 
#ifdef USE_GNUTLS
163
 
  return Curl_gtls_init();
164
 
#else
165
 
#ifdef USE_NSS
166
 
  return Curl_nss_init();
167
 
#else
168
 
#ifdef USE_QSOSSL
169
 
  return Curl_qsossl_init();
170
 
#else
171
 
  /* no SSL support */
172
 
  return 1;
173
 
#endif /* USE_QSOSSL */
174
 
#endif /* USE_NSS */
175
 
#endif /* USE_GNUTLS */
176
 
#endif /* USE_SSLEAY */
 
163
  return curlssl_init();
177
164
}
178
165
 
179
166
 
182
169
{
183
170
  if(init_ssl) {
184
171
    /* only cleanup if we did a previous init */
185
 
#ifdef USE_SSLEAY
186
 
    Curl_ossl_cleanup();
187
 
#else
188
 
#ifdef USE_GNUTLS
189
 
    Curl_gtls_cleanup();
190
 
#else
191
 
#ifdef USE_NSS
192
 
    Curl_nss_cleanup();
193
 
#else
194
 
#ifdef USE_QSOSSL
195
 
    Curl_qsossl_cleanup();
196
 
#endif /* USE_QSOSSL */
197
 
#endif /* USE_NSS */
198
 
#endif /* USE_GNUTLS */
199
 
#endif /* USE_SSLEAY */
 
172
    curlssl_cleanup();
200
173
    init_ssl = FALSE;
201
174
  }
202
175
}
204
177
CURLcode
205
178
Curl_ssl_connect(struct connectdata *conn, int sockindex)
206
179
{
207
 
#ifdef USE_SSL
208
 
  /* mark this is being ssl enabled from here on. */
 
180
  CURLcode res;
 
181
  /* mark this is being ssl-enabled from here on. */
209
182
  conn->ssl[sockindex].use = TRUE;
210
183
  conn->ssl[sockindex].state = ssl_connection_negotiating;
211
184
 
212
 
#ifdef USE_SSLEAY
213
 
  return Curl_ossl_connect(conn, sockindex);
214
 
#else
215
 
#ifdef USE_GNUTLS
216
 
  return Curl_gtls_connect(conn, sockindex);
217
 
#else
218
 
#ifdef USE_NSS
219
 
  return Curl_nss_connect(conn, sockindex);
220
 
#else
221
 
#ifdef USE_QSOSSL
222
 
  return Curl_qsossl_connect(conn, sockindex);
223
 
#endif /* USE_QSOSSL */
224
 
#endif /* USE_NSS */
225
 
#endif /* USE_GNUTLS */
226
 
#endif /* USE_SSLEAY */
227
 
 
228
 
#else
229
 
  /* without SSL */
230
 
  (void)conn;
231
 
  (void)sockindex;
232
 
  return CURLE_OK;
233
 
#endif /* USE_SSL */
 
185
  res = curlssl_connect(conn, sockindex);
 
186
 
 
187
  if(!res)
 
188
    Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */
 
189
 
 
190
  return res;
234
191
}
235
192
 
236
193
CURLcode
237
194
Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex,
238
195
                             bool *done)
239
196
{
240
 
#if defined(USE_SSL) && defined(USE_SSLEAY)
241
 
  /* mark this is being ssl enabled from here on. */
242
 
  conn->ssl[sockindex].use = TRUE;
243
 
  return Curl_ossl_connect_nonblocking(conn, sockindex, done);
244
 
 
245
 
#else
246
 
#ifdef USE_NSS
247
 
  *done = TRUE; /* fallback to BLOCKING */
248
 
  conn->ssl[sockindex].use = TRUE;
249
 
  return Curl_nss_connect(conn, sockindex);
250
 
#else
251
 
#ifdef USE_QSOSSL
252
 
  *done = TRUE; /* fallback to BLOCKING */
253
 
  conn->ssl[sockindex].use = TRUE;
254
 
  return Curl_qsossl_connect(conn, sockindex);
255
 
#else
256
 
  /* not implemented!
257
 
     fallback to BLOCKING call. */
258
 
  *done = TRUE;
259
 
  conn->ssl[sockindex].use = TRUE;
260
 
  return Curl_ssl_connect(conn, sockindex);
261
 
#endif /* USE_QSOSSL */
262
 
#endif /* USE_NSS */
263
 
#endif /* USE_SSLEAY */
 
197
#ifdef curlssl_connect_nonblocking
 
198
  /* mark this is being ssl requested from here on. */
 
199
  conn->ssl[sockindex].use = TRUE;
 
200
  return curlssl_connect_nonblocking(conn, sockindex, done);
 
201
#else
 
202
  *done = TRUE; /* fallback to BLOCKING */
 
203
  conn->ssl[sockindex].use = TRUE;
 
204
  return curlssl_connect(conn, sockindex);
 
205
#endif /* non-blocking connect support */
264
206
}
265
207
 
266
 
#ifdef USE_SSL
267
 
 
268
208
/*
269
209
 * Check if there's a session ID for the given connection in the cache, and if
270
210
 * there's one suitable, it is provided. Returns TRUE when no entry matched.
286
226
    if(!check->sessionid)
287
227
      /* not session ID means blank entry */
288
228
      continue;
289
 
    if(curl_strequal(conn->host.name, check->name) &&
 
229
    if(Curl_raw_equal(conn->host.name, check->name) &&
290
230
       (conn->remote_port == check->remote_port) &&
291
231
       Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
292
232
      /* yes, we have a session ID! */
311
251
    /* defensive check */
312
252
 
313
253
    /* free the ID the SSL-layer specific way */
314
 
#ifdef USE_SSLEAY
315
 
    Curl_ossl_session_free(session->sessionid);
316
 
#else
317
 
#ifdef USE_GNUTLS
318
 
    Curl_gtls_session_free(session->sessionid);
319
 
#else
320
 
#ifdef USE_QSOSSL
321
 
    /* No session handling for QsoSSL. */
322
 
#else
323
 
#ifdef USE_NSS
324
 
    /* NSS has its own session ID cache */
325
 
#endif /* USE_NSS */
326
 
#endif /* USE_QSOSSL */
327
 
#endif /* USE_GNUTLS */
328
 
#endif /* USE_SSLEAY */
 
254
    curlssl_session_free(session->sessionid);
 
255
 
329
256
    session->sessionid=NULL;
330
257
    session->age = 0; /* fresh */
331
258
 
398
325
}
399
326
 
400
327
 
401
 
#endif /* USE_SSL */
402
 
 
403
328
void Curl_ssl_close_all(struct SessionHandle *data)
404
329
{
405
 
#ifdef USE_SSL
406
330
  long i;
407
331
  /* kill the session ID cache */
408
332
  if(data->state.session) {
414
338
    free(data->state.session);
415
339
    data->state.session = NULL;
416
340
  }
417
 
#ifdef USE_SSLEAY
418
 
  Curl_ossl_close_all(data);
419
 
#else
420
 
#ifdef USE_GNUTLS
421
 
  Curl_gtls_close_all(data);
422
 
#else
423
 
#ifdef USE_NSS
424
 
  Curl_nss_close_all(data);
425
 
#else
426
 
#ifdef USE_QSOSSL
427
 
  Curl_qsossl_close_all(data);
428
 
#endif /* USE_QSOSSL */
429
 
#endif /* USE_NSS */
430
 
#endif /* USE_GNUTLS */
431
 
#endif /* USE_SSLEAY */
432
 
#else /* USE_SSL */
433
 
  (void)data;
434
 
#endif /* USE_SSL */
 
341
 
 
342
  curlssl_close_all(data);
435
343
}
436
344
 
437
345
void Curl_ssl_close(struct connectdata *conn, int sockindex)
438
346
{
439
347
  DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
440
 
 
441
 
#ifdef USE_SSLEAY
442
 
  Curl_ossl_close(conn, sockindex);
443
 
#endif /* USE_SSLEAY */
444
 
#ifdef USE_GNUTLS
445
 
  Curl_gtls_close(conn, sockindex);
446
 
#endif /* USE_GNUTLS */
447
 
#ifdef USE_NSS
448
 
  Curl_nss_close(conn, sockindex);
449
 
#endif /* USE_NSS */
450
 
#ifdef USE_QSOSSL
451
 
  Curl_qsossl_close(conn, sockindex);
452
 
#endif /* USE_QSOSSL */
453
 
#ifndef USE_SSL
454
 
  (void)conn;
455
 
  (void)sockindex;
456
 
#endif /* !USE_SSL */
 
348
  curlssl_close(conn, sockindex);
457
349
}
458
350
 
459
351
CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex)
460
352
{
461
 
#ifdef USE_SSLEAY
462
 
  if(Curl_ossl_shutdown(conn, sockindex))
463
 
    return CURLE_SSL_SHUTDOWN_FAILED;
464
 
#else
465
 
#ifdef USE_GNUTLS
466
 
  if(Curl_gtls_shutdown(conn, sockindex))
467
 
    return CURLE_SSL_SHUTDOWN_FAILED;
468
 
#else
469
 
#ifdef USE_QSOSSL
470
 
  if(Curl_qsossl_shutdown(conn, sockindex))
471
 
    return CURLE_SSL_SHUTDOWN_FAILED;
472
 
#endif /* USE_QSOSSL */
473
 
#endif /* USE_GNUTLS */
474
 
#endif /* USE_SSLEAY */
 
353
  if(curlssl_shutdown(conn, sockindex))
 
354
    return CURLE_SSL_SHUTDOWN_FAILED;
475
355
 
476
356
  conn->ssl[sockindex].use = FALSE; /* get back to ordinary socket usage */
477
357
  conn->ssl[sockindex].state = ssl_connection_none;
479
359
  return CURLE_OK;
480
360
}
481
361
 
482
 
/* Selects an (Open)SSL crypto engine
 
362
/* Selects an SSL crypto engine
483
363
 */
484
364
CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine)
485
365
{
486
 
#ifdef USE_SSLEAY
487
 
  return Curl_ossl_set_engine(data, engine);
488
 
#else
489
 
#ifdef USE_GNUTLS
490
 
  /* FIX: add code here */
491
 
  (void)data;
492
 
  (void)engine;
493
 
  return CURLE_FAILED_INIT;
494
 
#else
495
 
#ifdef USE_NSS
496
 
  /* NSS doesn't set an engine this way */
497
 
  (void)data;
498
 
  (void)engine;
499
 
  return CURLE_FAILED_INIT;
500
 
#else
501
 
#ifdef USE_QSOSSL
502
 
  /* QSOSSL doesn't set an engine this way */
503
 
  (void)data;
504
 
  (void)engine;
505
 
  return CURLE_FAILED_INIT;
506
 
#else
507
 
  /* no SSL layer */
508
 
  (void)data;
509
 
  (void)engine;
510
 
  return CURLE_FAILED_INIT;
511
 
#endif /* USE_QSOSSL */
512
 
#endif /* USE_NSS */
513
 
#endif /* USE_GNUTLS */
514
 
#endif /* USE_SSLEAY */
 
366
  return curlssl_set_engine(data, engine);
515
367
}
516
368
 
517
 
/* Selects an (Open?)SSL crypto engine
 
369
/* Selects the default SSL crypto engine
518
370
 */
519
371
CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data)
520
372
{
521
 
#ifdef USE_SSLEAY
522
 
  return Curl_ossl_set_engine_default(data);
523
 
#else
524
 
#ifdef USE_GNUTLS
525
 
  /* FIX: add code here */
526
 
  (void)data;
527
 
  return CURLE_FAILED_INIT;
528
 
#else
529
 
#ifdef USE_NSS
530
 
  /* A no-op for NSS */
531
 
  (void)data;
532
 
  return CURLE_FAILED_INIT;
533
 
#else
534
 
#ifdef USE_QSOSSL
535
 
  /* A no-op for QSOSSL */
536
 
  (void)data;
537
 
  return CURLE_FAILED_INIT;
538
 
#else
539
 
  /* No SSL layer */
540
 
  (void)data;
541
 
  return CURLE_FAILED_INIT;
542
 
#endif /* USE_QSOSSL */
543
 
#endif /* USE_NSS */
544
 
#endif /* USE_GNUTLS */
545
 
#endif /* USE_SSLEAY */
 
373
  return curlssl_set_engine_default(data);
546
374
}
547
375
 
548
376
/* Return list of OpenSSL crypto engine names. */
549
377
struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data)
550
378
{
551
 
#ifdef USE_SSLEAY
552
 
  return Curl_ossl_engines_list(data);
553
 
#else
554
 
#ifdef USE_GNUTLS
555
 
  /* FIX: add code here? */
556
 
  (void)data;
557
 
  return NULL;
558
 
#else
559
 
#ifdef USE_NSS
560
 
  /* In theory we could return the PKCS#11 modules loaded but that
561
 
   * would just confuse things */
562
 
  (void)data;
563
 
  return NULL;
564
 
#else
565
 
#ifdef USE_QSOSSL
566
 
  /* No engine support in QSOSSL. */
567
 
  (void)data;
568
 
  return NULL;
569
 
#else
570
 
  (void)data;
571
 
  return NULL;
572
 
#endif /* USE_QSOSSL */
573
 
#endif /* USE_NSS */
574
 
#endif /* USE_GNUTLS */
575
 
#endif /* USE_SSLEAY */
 
379
  return curlssl_engines_list(data);
576
380
}
577
381
 
578
382
/* return number of sent (non-SSL) bytes */
581
385
                      const void *mem,
582
386
                      size_t len)
583
387
{
584
 
#ifdef USE_SSLEAY
585
 
  return Curl_ossl_send(conn, sockindex, mem, len);
586
 
#else
587
 
#ifdef USE_GNUTLS
588
 
  return Curl_gtls_send(conn, sockindex, mem, len);
589
 
#else
590
 
#ifdef USE_NSS
591
 
  return Curl_nss_send(conn, sockindex, mem, len);
592
 
#else
593
 
#ifdef USE_QSOSSL
594
 
  return Curl_qsossl_send(conn, sockindex, mem, len);
595
 
#else
596
 
  (void)conn;
597
 
  (void)sockindex;
598
 
  (void)mem;
599
 
  (void)len;
600
 
  return 0;
601
 
#endif /* USE_QSOSSL */
602
 
#endif /* USE_NSS */
603
 
#endif /* USE_GNUTLS */
604
 
#endif /* USE_SSLEAY */
 
388
  return curlssl_send(conn, sockindex, mem, len);
605
389
}
606
390
 
607
391
/* return number of received (decrypted) bytes */
615
399
                      char *mem,                /* store read data here */
616
400
                      size_t len)               /* max amount to read */
617
401
{
618
 
#ifdef USE_SSL
619
402
  ssize_t nread;
620
403
  bool block = FALSE;
621
404
 
622
 
#ifdef USE_SSLEAY
623
 
  nread = Curl_ossl_recv(conn, sockindex, mem, len, &block);
624
 
#else
625
 
#ifdef USE_GNUTLS
626
 
  nread = Curl_gtls_recv(conn, sockindex, mem, len, &block);
627
 
#else
628
 
#ifdef USE_NSS
629
 
  nread = Curl_nss_recv(conn, sockindex, mem, len, &block);
630
 
#else
631
 
#ifdef USE_QSOSSL
632
 
  nread = Curl_qsossl_recv(conn, sockindex, mem, len, &block);
633
 
#endif /* USE_QSOSSL */
634
 
#endif /* USE_NSS */
635
 
#endif /* USE_GNUTLS */
636
 
#endif /* USE_SSLEAY */
 
405
  nread = curlssl_recv(conn, sockindex, mem, len, &block);
637
406
  if(nread == -1) {
638
407
    if(!block)
639
408
      return 0; /* this is a true error, not EWOULDBLOCK */
642
411
  }
643
412
 
644
413
  return nread;
645
 
 
646
 
#else /* USE_SSL */
647
 
  (void)conn;
648
 
  (void)sockindex;
649
 
  (void)mem;
650
 
  (void)len;
651
 
  return 0;
652
 
#endif /* USE_SSL */
653
414
}
654
415
 
655
416
 
659
420
 */
660
421
CURLcode Curl_ssl_initsessions(struct SessionHandle *data, long amount)
661
422
{
662
 
#ifdef USE_SSL
663
423
  struct curl_ssl_session *session;
664
424
 
665
425
  if(data->state.session)
666
426
    /* this is just a precaution to prevent multiple inits */
667
427
    return CURLE_OK;
668
428
 
669
 
  session = (struct curl_ssl_session *)
670
 
    calloc(sizeof(struct curl_ssl_session), amount);
 
429
  session = calloc(sizeof(struct curl_ssl_session), amount);
671
430
  if(!session)
672
431
    return CURLE_OUT_OF_MEMORY;
673
432
 
675
434
  data->set.ssl.numsessions = amount;
676
435
  data->state.session = session;
677
436
  data->state.sessionage = 1; /* this is brand new */
678
 
#else
679
 
  /* without SSL, do nothing */
680
 
  (void)data;
681
 
  (void)amount;
682
 
#endif
683
 
 
684
437
  return CURLE_OK;
685
438
}
686
439
 
687
440
size_t Curl_ssl_version(char *buffer, size_t size)
688
441
{
689
 
#ifdef USE_SSLEAY
690
 
  return Curl_ossl_version(buffer, size);
691
 
#else
692
 
#ifdef USE_GNUTLS
693
 
  return Curl_gtls_version(buffer, size);
694
 
#else
695
 
#ifdef USE_NSS
696
 
  return Curl_nss_version(buffer, size);
697
 
#else
698
 
#ifdef USE_QSOSSL
699
 
  return Curl_qsossl_version(buffer, size);
700
 
#else
701
 
  (void)buffer;
702
 
  (void)size;
703
 
  return 0; /* no SSL support */
704
 
#endif /* USE_QSOSSL */
705
 
#endif /* USE_NSS */
706
 
#endif /* USE_GNUTLS */
707
 
#endif /* USE_SSLEAY */
 
442
  return curlssl_version(buffer, size);
708
443
}
709
444
 
710
 
 
711
445
/*
712
446
 * This function tries to determine connection status.
713
447
 *
718
452
 */
719
453
int Curl_ssl_check_cxn(struct connectdata *conn)
720
454
{
721
 
#ifdef USE_SSLEAY
722
 
  return Curl_ossl_check_cxn(conn);
723
 
#else
724
 
#ifdef USE_NSS
725
 
  return Curl_nss_check_cxn(conn);
726
 
#else
727
 
#ifdef USE_QSOSSL
728
 
  return Curl_qsossl_check_cxn(conn);
729
 
#else
730
 
  (void)conn;
731
 
  /* TODO: we lack implementation of this for GnuTLS */
732
 
  return -1; /* connection status unknown */
733
 
#endif /* USE_QSOSSL */
734
 
#endif /* USE_NSS */
735
 
#endif /* USE_SSLEAY */
 
455
  return curlssl_check_cxn(conn);
736
456
}
737
457
 
738
458
bool Curl_ssl_data_pending(const struct connectdata *conn,
739
459
                           int connindex)
740
460
{
741
 
#ifdef USE_SSLEAY
742
 
  /* OpenSSL-specific */
743
 
  if(conn->ssl[connindex].handle)
744
 
    /* SSL is in use */
745
 
    return (bool)(0 != SSL_pending(conn->ssl[connindex].handle));
746
 
#else
747
 
  (void)conn;
748
 
  (void)connindex;
749
 
#endif
750
 
  return FALSE; /* nothing pending */
 
461
  return curlssl_data_pending(conn, connindex);
 
462
}
751
463
 
 
464
void Curl_ssl_free_certinfo(struct SessionHandle *data)
 
465
{
 
466
  int i;
 
467
  struct curl_certinfo *ci = &data->info.certs;
 
468
  if(ci->num_of_certs) {
 
469
    /* free all individual lists used */
 
470
    for(i=0; i<ci->num_of_certs; i++)
 
471
      curl_slist_free_all(ci->certinfo[i]);
 
472
    free(ci->certinfo); /* free the actual array too */
 
473
    ci->num_of_certs = 0;
 
474
  }
752
475
}
 
476
#endif /* USE_SSL */