~ubuntu-branches/ubuntu/lucid/curl/lucid-security

« back to all changes in this revision

Viewing changes to lib/ssluse.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2009-04-29 11:10:29 UTC
  • mfrom: (3.2.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090429111029-2j5eiyokfw2bw049
Tags: 7.19.4-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Drop build dependencies: stunnel, libdb4.6-dev, libssh2-1-dev
  - Add build-dependency on openssh-server
  - Drop libssh2-1-dev from libcurl4-openssl-dev's Depends.
  - Call automake-1.9 with --add-missing --copy --force
* drop debian/patches/security_CVE-2009-0037.patch 
  - this patch is part of 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: ssluse.c,v 1.199 2008-05-26 01:59:00 yangtse Exp $
 
21
 * $Id: ssluse.c,v 1.215 2009-01-26 14:36:22 bagder Exp $
22
22
 ***************************************************************************/
23
23
 
24
24
/*
50
50
#include "strequal.h"
51
51
#include "select.h"
52
52
#include "sslgen.h"
 
53
#include "rawstr.h"
53
54
 
54
55
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
55
56
#include <curl/mprintf.h>
108
109
#define SSL_METHOD_QUAL
109
110
#endif
110
111
 
 
112
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
 
113
/* 0.9.6 didn't have X509_STORE_set_flags() */
 
114
#define HAVE_X509_STORE_SET_FLAGS 1
 
115
#else
 
116
#define X509_STORE_set_flags(x,y)
 
117
#endif
 
118
 
111
119
/*
112
120
 * Number of bytes to read from the random number seed file. This must be
113
121
 * a finite value (because some entropy "files" like /dev/urandom have
277
285
{
278
286
  if(!type || !type[0])
279
287
    return SSL_FILETYPE_PEM;
280
 
  if(curl_strequal(type, "PEM"))
 
288
  if(Curl_raw_equal(type, "PEM"))
281
289
    return SSL_FILETYPE_PEM;
282
 
  if(curl_strequal(type, "DER"))
 
290
  if(Curl_raw_equal(type, "DER"))
283
291
    return SSL_FILETYPE_ASN1;
284
 
  if(curl_strequal(type, "ENG"))
 
292
  if(Curl_raw_equal(type, "ENG"))
285
293
    return SSL_FILETYPE_ENGINE;
286
 
  if(curl_strequal(type, "P12"))
 
294
  if(Curl_raw_equal(type, "P12"))
287
295
    return SSL_FILETYPE_PKCS12;
288
296
  return -1;
289
297
}
547
555
  return(1);
548
556
}
549
557
 
 
558
/* returns non-zero on failure */
 
559
static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
 
560
{
 
561
#if 0
 
562
  return X509_NAME_oneline(a, buf, size);
 
563
#else
 
564
  BIO *bio_out = BIO_new(BIO_s_mem());
 
565
  BUF_MEM *biomem;
 
566
  int rc;
 
567
 
 
568
  rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_CPLUS_SPC);
 
569
  BIO_get_mem_ptr(bio_out, &biomem);
 
570
 
 
571
  if((size_t)biomem->length < size)
 
572
    size = biomem->length;
 
573
  else
 
574
    size--; /* don't overwrite the buffer end */
 
575
 
 
576
  memcpy(buf, biomem->data, size);
 
577
  buf[size]=0;
 
578
 
 
579
  BIO_free(bio_out);
 
580
 
 
581
  return !rc;
 
582
#endif
 
583
}
 
584
 
550
585
static
551
586
int cert_verify_callback(int ok, X509_STORE_CTX *ctx)
552
587
{
554
589
  char buf[256];
555
590
 
556
591
  err_cert=X509_STORE_CTX_get_current_cert(ctx);
557
 
  X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
 
592
  (void)x509_name_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
558
593
  return ok;
559
594
}
560
595
 
879
914
  return 0;
880
915
}
881
916
 
882
 
static int asn1_output(struct connectdata *conn,
883
 
                       const char *prefix,
884
 
                       const ASN1_UTCTIME *tm)
 
917
static int asn1_output(const ASN1_UTCTIME *tm,
 
918
                       char *buf,
 
919
                       size_t sizeofbuf)
885
920
{
886
921
  const char *asn1_string;
887
922
  int gmt=FALSE;
888
923
  int i;
889
924
  int year=0,month=0,day=0,hour=0,minute=0,second=0;
890
 
  struct SessionHandle *data = conn->data;
891
 
 
892
 
#ifdef CURL_DISABLE_VERBOSE_STRINGS
893
 
  (void)prefix;
894
 
#endif
895
 
 
896
 
  if(!data->set.verbose)
897
 
    return 0;
898
925
 
899
926
  i=tm->length;
900
927
  asn1_string=(const char *)tm->data;
923
950
     (asn1_string[11] >= '0') && (asn1_string[11] <= '9'))
924
951
    second= (asn1_string[10]-'0')*10+(asn1_string[11]-'0');
925
952
 
926
 
  infof(data,
927
 
        "%s%04d-%02d-%02d %02d:%02d:%02d %s\n",
928
 
        prefix, year+1900, month, day, hour, minute, second, (gmt?"GMT":""));
 
953
  snprintf(buf, sizeofbuf,
 
954
           "%04d-%02d-%02d %02d:%02d:%02d %s",
 
955
           year+1900, month, day, hour, minute, second, (gmt?"GMT":""));
929
956
 
930
957
  return 0;
931
958
}
967
994
      break;
968
995
    }
969
996
 
970
 
    if(toupper(c) != toupper(*hostname++))
 
997
    if(Curl_raw_toupper(c) != Curl_raw_toupper(*hostname++))
971
998
      break;
972
999
  }
973
1000
  return HOST_NOMATCH;
980
1007
      !hostname || !*hostname) /* sanity check */
981
1008
    return 0;
982
1009
 
983
 
  if(curl_strequal(hostname,match_pattern)) /* trivial case */
 
1010
  if(Curl_raw_equal(hostname, match_pattern)) /* trivial case */
984
1011
    return 1;
985
1012
 
986
1013
  if(hostmatch(hostname,match_pattern) == HOST_MATCH)
1293
1320
  struct SessionHandle *data = conn->data;
1294
1321
  SSL_METHOD_QUAL SSL_METHOD *req_method=NULL;
1295
1322
  void *ssl_sessionid=NULL;
 
1323
  X509_LOOKUP *lookup=NULL;
1296
1324
  curl_socket_t sockfd = conn->sock[sockindex];
1297
1325
  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1298
1326
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1357
1385
     enable the bug workaround options if compatibility with somewhat broken
1358
1386
     implementations is desired."
1359
1387
 
 
1388
     The "-no_ticket" option was introduced in Openssl0.9.8j. It's a flag to
 
1389
     disable "rfc4507bis session ticket support".  rfc4507bis was later turned
 
1390
     into the proper RFC5077 it seems: http://tools.ietf.org/html/rfc5077
 
1391
 
 
1392
     The enabled extension concerns the session management. I wonder how often
 
1393
     libcurl stops a connection and then resumes a TLS session. also, sending
 
1394
     the session data is some overhead. .I suggest that you just use your
 
1395
     proposed patch (which explicitly disables TICKET).
 
1396
 
 
1397
     If someone writes an application with libcurl and openssl who wants to
 
1398
     enable the feature, one can do this in the SSL callback.
 
1399
 
1360
1400
  */
1361
 
  SSL_CTX_set_options(connssl->ctx, SSL_OP_ALL);
 
1401
#ifdef SSL_OP_NO_TICKET
 
1402
  /* expect older openssl releases to not have this define so only use it if
 
1403
     present */
 
1404
#define CURL_CTX_OPTIONS SSL_OP_ALL|SSL_OP_NO_TICKET
 
1405
#else
 
1406
#define CURL_CTX_OPTIONS SSL_OP_ALL
 
1407
#endif
 
1408
 
 
1409
  SSL_CTX_set_options(connssl->ctx, CURL_CTX_OPTIONS);
1362
1410
 
1363
1411
  /* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */
1364
1412
  if(data->set.ssl.version == CURL_SSLVERSION_DEFAULT)
1429
1477
          data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
1430
1478
          "none");
1431
1479
  }
 
1480
 
 
1481
  if (data->set.str[STRING_SSL_CRLFILE]) {
 
1482
    /* tell SSL where to find CRL file that is used to check certificate
 
1483
     * revocation */
 
1484
    lookup=X509_STORE_add_lookup(connssl->ctx->cert_store,X509_LOOKUP_file());
 
1485
    if ( !lookup ||
 
1486
         (X509_load_crl_file(lookup,data->set.str[STRING_SSL_CRLFILE],
 
1487
                             X509_FILETYPE_PEM)!=1) ) {
 
1488
      failf(data,"error loading CRL file :\n"
 
1489
            "  CRLfile: %s\n",
 
1490
            data->set.str[STRING_SSL_CRLFILE]?
 
1491
            data->set.str[STRING_SSL_CRLFILE]: "none");
 
1492
      return CURLE_SSL_CRL_BADFILE;
 
1493
    }
 
1494
    else {
 
1495
      /* Everything is fine. */
 
1496
      infof(data, "successfully load CRL file:\n");
 
1497
      X509_STORE_set_flags(connssl->ctx->cert_store,
 
1498
                           X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
 
1499
    }
 
1500
    infof(data,
 
1501
          "  CRLfile: %s\n", data->set.str[STRING_SSL_CRLFILE] ?
 
1502
          data->set.str[STRING_SSL_CRLFILE]: "none");
 
1503
  }
 
1504
 
1432
1505
  /* SSL always tries to verify the peer, this only says whether it should
1433
1506
   * fail to connect if the verification fails, or if it should continue
1434
1507
   * anyway. In the latter case the result of the verification is checked with
1586
1659
  }
1587
1660
}
1588
1661
 
 
1662
static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
 
1663
{
 
1664
  int i, ilen;
 
1665
 
 
1666
  if((ilen = (int)len) < 0)
 
1667
    return 1; /* buffer too big */
 
1668
 
 
1669
  i = i2t_ASN1_OBJECT(buf, ilen, a);
 
1670
 
 
1671
  if(i >= ilen)
 
1672
    return 1; /* buffer too small */
 
1673
 
 
1674
  return 0;
 
1675
}
 
1676
 
 
1677
static CURLcode push_certinfo_len(struct SessionHandle *data,
 
1678
                                  int certnum,
 
1679
                                  const char *label,
 
1680
                                  const char *value,
 
1681
                                  size_t valuelen)
 
1682
{
 
1683
  struct curl_certinfo *ci = &data->info.certs;
 
1684
  char *outp;
 
1685
  struct curl_slist *nl;
 
1686
  CURLcode res = CURLE_OK;
 
1687
  size_t labellen = strlen(label);
 
1688
  size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */
 
1689
 
 
1690
  outp = malloc(outlen);
 
1691
  if(!outp)
 
1692
    return CURLE_OUT_OF_MEMORY;
 
1693
 
 
1694
  /* sprintf the label and colon */
 
1695
  snprintf(outp, outlen, "%s:", label);
 
1696
 
 
1697
  /* memcpy the value (it might not be zero terminated) */
 
1698
  memcpy(&outp[labellen+1], value, valuelen);
 
1699
 
 
1700
  /* zero terminate the output */
 
1701
  outp[labellen + 1 + valuelen] = 0;
 
1702
 
 
1703
  /* TODO: we should rather introduce an internal API that can do the
 
1704
     equivalent of curl_slist_append but doesn't strdup() the given data as
 
1705
     like in this place the extra malloc/free is totally pointless */
 
1706
  nl = curl_slist_append(ci->certinfo[certnum], outp);
 
1707
  if(!nl) {
 
1708
    curl_slist_free_all(ci->certinfo[certnum]);
 
1709
    res = CURLE_OUT_OF_MEMORY;
 
1710
  }
 
1711
  else
 
1712
    ci->certinfo[certnum] = nl;
 
1713
 
 
1714
  free(outp);
 
1715
 
 
1716
  return res;
 
1717
}
 
1718
 
 
1719
/* this is a convenience function for push_certinfo_len that takes a zero
 
1720
   terminated value */
 
1721
static CURLcode push_certinfo(struct SessionHandle *data,
 
1722
                              int certnum,
 
1723
                              const char *label,
 
1724
                              const char *value)
 
1725
{
 
1726
  size_t valuelen = strlen(value);
 
1727
 
 
1728
  return push_certinfo_len(data, certnum, label, value, valuelen);
 
1729
}
 
1730
 
 
1731
static void pubkey_show(struct SessionHandle *data,
 
1732
                        int num,
 
1733
                        const char *type,
 
1734
                        const char *name,
 
1735
                        unsigned char *raw,
 
1736
                        int len)
 
1737
{
 
1738
  char buffer[1024];
 
1739
  size_t left = sizeof(buffer);
 
1740
  int i;
 
1741
  char *ptr=buffer;
 
1742
  char namebuf[32];
 
1743
 
 
1744
  snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
 
1745
 
 
1746
  for(i=0; i< len; i++) {
 
1747
    snprintf(ptr, left, "%02x:", raw[i]);
 
1748
    ptr += 3;
 
1749
    left -= 3;
 
1750
  }
 
1751
  infof(data, "   %s: %s\n", namebuf, buffer);
 
1752
  push_certinfo(data, num, namebuf, buffer);
 
1753
}
 
1754
 
 
1755
#define print_pubkey_BN(_type, _name, _num)    \
 
1756
do {                              \
 
1757
  if (pubkey->pkey._type->_name != NULL) { \
 
1758
    int len = BN_num_bytes(pubkey->pkey._type->_name); \
 
1759
    if(len < (int)sizeof(buf)) {                       \
 
1760
      BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)buf); \
 
1761
      buf[len] = 0; \
 
1762
      pubkey_show(data, _num, #_type, #_name, (unsigned char*)buf, len); \
 
1763
    } \
 
1764
  } \
 
1765
} while (0)
 
1766
 
 
1767
static int X509V3_ext(struct SessionHandle *data,
 
1768
                      int certnum,
 
1769
                      STACK_OF(X509_EXTENSION) *exts)
 
1770
{
 
1771
  int i;
 
1772
  size_t j;
 
1773
 
 
1774
  if(sk_X509_EXTENSION_num(exts) <= 0)
 
1775
    /* no extensions, bail out */
 
1776
    return 1;
 
1777
 
 
1778
  for (i=0; i<sk_X509_EXTENSION_num(exts); i++) {
 
1779
    ASN1_OBJECT *obj;
 
1780
    X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
 
1781
    BIO *bio_out = BIO_new(BIO_s_mem());
 
1782
    BUF_MEM *biomem;
 
1783
    char buf[512];
 
1784
    char *ptr=buf;
 
1785
    char namebuf[128];
 
1786
 
 
1787
    obj = X509_EXTENSION_get_object(ext);
 
1788
 
 
1789
    asn1_object_dump(obj, namebuf, sizeof(namebuf));
 
1790
 
 
1791
    infof(data, "%s: %s\n", namebuf,
 
1792
          X509_EXTENSION_get_critical(ext)?"(critical)":"");
 
1793
 
 
1794
    if(!X509V3_EXT_print(bio_out, ext, 0, 0))
 
1795
      M_ASN1_OCTET_STRING_print(bio_out, ext->value);
 
1796
 
 
1797
    BIO_get_mem_ptr(bio_out, &biomem);
 
1798
 
 
1799
    /* biomem->length bytes at biomem->data, this little loop here is only
 
1800
       done for the infof() call, we send the "raw" data to the certinfo
 
1801
       function */
 
1802
    for(j=0; j<(size_t)biomem->length; j++) {
 
1803
      const char *sep="";
 
1804
      if(biomem->data[j] == '\n') {
 
1805
        sep=", ";
 
1806
        j++; /* skip the newline */
 
1807
      };
 
1808
      while((biomem->data[j] == ' ') && (j<(size_t)biomem->length))
 
1809
        j++;
 
1810
      if(j<(size_t)biomem->length)
 
1811
        ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep, biomem->data[j]);
 
1812
    }
 
1813
    infof(data, "  %s\n", buf);
 
1814
 
 
1815
    push_certinfo(data, certnum, namebuf, buf);
 
1816
 
 
1817
    BIO_free(bio_out);
 
1818
 
 
1819
  }
 
1820
  return 0; /* all is fine */
 
1821
}
 
1822
 
 
1823
 
 
1824
static void X509_signature(struct SessionHandle *data,
 
1825
                           int numcert,
 
1826
                           ASN1_STRING *sig)
 
1827
{
 
1828
  char buf[1024];
 
1829
  char *ptr = buf;
 
1830
  int i;
 
1831
  for (i=0; i<sig->length; i++)
 
1832
    ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%02x:", sig->data[i]);
 
1833
 
 
1834
  infof(data, " Signature: %s\n", buf);
 
1835
  push_certinfo(data, numcert, "Signature", buf);
 
1836
}
 
1837
 
 
1838
static void dumpcert(struct SessionHandle *data, X509 *x, int numcert)
 
1839
{
 
1840
  BIO *bio_out = BIO_new(BIO_s_mem());
 
1841
  BUF_MEM *biomem;
 
1842
 
 
1843
  /* this outputs the cert in this 64 column wide style with newlines and
 
1844
     -----BEGIN CERTIFICATE----- texts and more */
 
1845
  PEM_write_bio_X509(bio_out, x);
 
1846
 
 
1847
  BIO_get_mem_ptr(bio_out, &biomem);
 
1848
 
 
1849
  infof(data, "%s\n", biomem->data);
 
1850
 
 
1851
  push_certinfo_len(data, numcert, "Cert", biomem->data, biomem->length);
 
1852
 
 
1853
  BIO_free(bio_out);
 
1854
 
 
1855
}
 
1856
 
 
1857
 
 
1858
static int init_certinfo(struct SessionHandle *data,
 
1859
                         int num)
 
1860
{
 
1861
  struct curl_certinfo *ci = &data->info.certs;
 
1862
  struct curl_slist **table;
 
1863
 
 
1864
  Curl_ssl_free_certinfo(data);
 
1865
 
 
1866
  ci->num_of_certs = num;
 
1867
  table = calloc(sizeof(struct curl_slist *) * num, 1);
 
1868
  if(!table)
 
1869
    return 1;
 
1870
 
 
1871
  ci->certinfo = table;
 
1872
  return 0;
 
1873
}
 
1874
 
 
1875
static CURLcode get_cert_chain(struct connectdata *conn,
 
1876
                               struct ssl_connect_data *connssl)
 
1877
 
 
1878
{
 
1879
  STACK_OF(X509) *sk;
 
1880
  int i;
 
1881
  char buf[512];
 
1882
  struct SessionHandle *data = conn->data;
 
1883
  int numcerts;
 
1884
 
 
1885
  sk = SSL_get_peer_cert_chain(connssl->handle);
 
1886
 
 
1887
  if(!sk)
 
1888
    return CURLE_OUT_OF_MEMORY;
 
1889
 
 
1890
  numcerts = sk_X509_num(sk);
 
1891
 
 
1892
  if(init_certinfo(data, numcerts))
 
1893
    return CURLE_OUT_OF_MEMORY;
 
1894
 
 
1895
  infof(data, "--- Certificate chain\n");
 
1896
  for (i=0; i<numcerts; i++) {
 
1897
    long value;
 
1898
    ASN1_INTEGER *num;
 
1899
    ASN1_TIME *certdate;
 
1900
 
 
1901
    /* get the certs in "importance order" */
 
1902
#if 0
 
1903
    X509 *x = sk_X509_value(sk, numcerts - i - 1);
 
1904
#else
 
1905
    X509 *x = sk_X509_value(sk, i);
 
1906
#endif
 
1907
 
 
1908
    X509_CINF *cinf;
 
1909
    EVP_PKEY *pubkey=NULL;
 
1910
    int j;
 
1911
    char *ptr;
 
1912
 
 
1913
    (void)x509_name_oneline(X509_get_subject_name(x), buf, sizeof(buf));
 
1914
    infof(data, "%2d Subject: %s\n",i,buf);
 
1915
    push_certinfo(data, i, "Subject", buf);
 
1916
 
 
1917
    (void)x509_name_oneline(X509_get_issuer_name(x), buf, sizeof(buf));
 
1918
    infof(data, "   Issuer: %s\n",buf);
 
1919
    push_certinfo(data, i, "Issuer", buf);
 
1920
 
 
1921
    value = X509_get_version(x);
 
1922
    infof(data, "   Version: %lu (0x%lx)\n", value+1, value);
 
1923
    snprintf(buf, sizeof(buf), "%lx", value);
 
1924
    push_certinfo(data, i, "Version", buf); /* hex */
 
1925
 
 
1926
    num=X509_get_serialNumber(x);
 
1927
    if (num->length <= 4) {
 
1928
      value = ASN1_INTEGER_get(num);
 
1929
      infof(data,"   Serial Number: %ld (0x%lx)\n", value, value);
 
1930
      snprintf(buf, sizeof(buf), "%lx", value);
 
1931
    }
 
1932
    else {
 
1933
 
 
1934
      ptr = buf;
 
1935
      *ptr++ = 0;
 
1936
      if(num->type == V_ASN1_NEG_INTEGER)
 
1937
        *ptr++='-';
 
1938
 
 
1939
      for (j=0; j<num->length; j++) {
 
1940
        /* TODO: length restrictions */
 
1941
        snprintf(ptr, 3, "%02x%c",num->data[j],
 
1942
                 ((j+1 == num->length)?'\n':':'));
 
1943
        ptr += 3;
 
1944
      }
 
1945
      if(num->length)
 
1946
        infof(data,"   Serial Number: %s\n", buf);
 
1947
      else
 
1948
        buf[0]=0;
 
1949
    }
 
1950
    if(buf[0])
 
1951
      push_certinfo(data, i, "Serial Number", buf); /* hex */
 
1952
 
 
1953
    cinf = x->cert_info;
 
1954
 
 
1955
    j = asn1_object_dump(cinf->signature->algorithm, buf, sizeof(buf));
 
1956
    if(!j) {
 
1957
      infof(data, "   Signature Algorithm: %s\n", buf);
 
1958
      push_certinfo(data, i, "Signature Algorithm", buf);
 
1959
    }
 
1960
 
 
1961
    certdate = X509_get_notBefore(x);
 
1962
    asn1_output(certdate, buf, sizeof(buf));
 
1963
    infof(data, "   Start date: %s\n", buf);
 
1964
    push_certinfo(data, i, "Start date", buf);
 
1965
 
 
1966
    certdate = X509_get_notAfter(x);
 
1967
    asn1_output(certdate, buf, sizeof(buf));
 
1968
    infof(data, "   Expire date: %s\n", buf);
 
1969
    push_certinfo(data, i, "Expire date", buf);
 
1970
 
 
1971
    j = asn1_object_dump(cinf->key->algor->algorithm, buf, sizeof(buf));
 
1972
    if(!j) {
 
1973
      infof(data, "   Public Key Algorithm: %s\n", buf);
 
1974
      push_certinfo(data, i, "Public Key Algorithm", buf);
 
1975
    }
 
1976
 
 
1977
    pubkey = X509_get_pubkey(x);
 
1978
    if(!pubkey)
 
1979
      infof(data, "   Unable to load public key\n");
 
1980
    else {
 
1981
      switch(pubkey->type) {
 
1982
      case EVP_PKEY_RSA:
 
1983
        infof(data,  "   RSA Public Key (%d bits)\n",
 
1984
              BN_num_bits(pubkey->pkey.rsa->n));
 
1985
        snprintf(buf, sizeof(buf), "%d", BN_num_bits(pubkey->pkey.rsa->n));
 
1986
        push_certinfo(data, i, "RSA Public Key", buf);
 
1987
 
 
1988
        print_pubkey_BN(rsa, n, i);
 
1989
        print_pubkey_BN(rsa, e, i);
 
1990
        print_pubkey_BN(rsa, d, i);
 
1991
        print_pubkey_BN(rsa, p, i);
 
1992
        print_pubkey_BN(rsa, q, i);
 
1993
        print_pubkey_BN(rsa, dmp1, i);
 
1994
        print_pubkey_BN(rsa, dmq1, i);
 
1995
        print_pubkey_BN(rsa, iqmp, i);
 
1996
        break;
 
1997
      case EVP_PKEY_DSA:
 
1998
        print_pubkey_BN(dsa, p, i);
 
1999
        print_pubkey_BN(dsa, q, i);
 
2000
        print_pubkey_BN(dsa, g, i);
 
2001
        print_pubkey_BN(dsa, priv_key, i);
 
2002
        print_pubkey_BN(dsa, pub_key, i);
 
2003
        break;
 
2004
      case EVP_PKEY_DH:
 
2005
        print_pubkey_BN(dh, p, i);
 
2006
        print_pubkey_BN(dh, g, i);
 
2007
        print_pubkey_BN(dh, priv_key, i);
 
2008
        print_pubkey_BN(dh, pub_key, i);
 
2009
        break;
 
2010
#if 0
 
2011
      case EVP_PKEY_EC: /* symbol not present in OpenSSL 0.9.6 */
 
2012
        /* left TODO */
 
2013
        break;
 
2014
#endif
 
2015
      }
 
2016
    }
 
2017
 
 
2018
    X509V3_ext(data, i, cinf->extensions);
 
2019
 
 
2020
    X509_signature(data, i, x->signature);
 
2021
 
 
2022
    dumpcert(data, x, i);
 
2023
  }
 
2024
 
 
2025
  return CURLE_OK;
 
2026
}
 
2027
 
1589
2028
/*
1590
2029
 * Get the server cert, verify it and show it etc, only call failf() if the
1591
2030
 * 'strict' argument is TRUE as otherwise all this is for informational
1599
2038
                           bool strict)
1600
2039
{
1601
2040
  CURLcode retcode = CURLE_OK;
1602
 
  char *str;
 
2041
  int rc;
1603
2042
  long lerr;
1604
2043
  ASN1_TIME *certdate;
1605
2044
  struct SessionHandle *data = conn->data;
 
2045
  X509 *issuer;
 
2046
  FILE *fp;
 
2047
  char buffer[256];
 
2048
 
 
2049
  if(data->set.ssl.certinfo)
 
2050
    /* we've been asked to gather certificate info! */
 
2051
    (void)get_cert_chain(conn, connssl);
 
2052
 
 
2053
  data->set.ssl.certverifyresult = !X509_V_OK;
 
2054
 
1606
2055
  connssl->server_cert = SSL_get_peer_certificate(connssl->handle);
1607
2056
  if(!connssl->server_cert) {
1608
2057
    if(strict)
1611
2060
  }
1612
2061
  infof (data, "Server certificate:\n");
1613
2062
 
1614
 
  str = X509_NAME_oneline(X509_get_subject_name(connssl->server_cert),
1615
 
                          NULL, 0);
1616
 
  if(!str) {
 
2063
  rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert),
 
2064
                          buffer, sizeof(buffer));
 
2065
  if(rc) {
1617
2066
    if(strict)
1618
2067
      failf(data, "SSL: couldn't get X509-subject!");
1619
2068
    X509_free(connssl->server_cert);
1620
2069
    connssl->server_cert = NULL;
1621
2070
    return CURLE_SSL_CONNECT_ERROR;
1622
2071
  }
1623
 
  infof(data, "\t subject: %s\n", str);
1624
 
  CRYPTO_free(str);
 
2072
  infof(data, "\t subject: %s\n", buffer);
1625
2073
 
1626
2074
  certdate = X509_get_notBefore(connssl->server_cert);
1627
 
  asn1_output(conn, "\t start date: ", certdate);
 
2075
  asn1_output(certdate, buffer, sizeof(buffer));
 
2076
  infof(data, "\t start date: %s\n", buffer);
1628
2077
 
1629
2078
  certdate = X509_get_notAfter(connssl->server_cert);
1630
 
  asn1_output(conn, "\t expire date: ", certdate);
 
2079
  asn1_output(certdate, buffer, sizeof(buffer));
 
2080
  infof(data, "\t expire date: %s\n", buffer);
1631
2081
 
1632
2082
  if(data->set.ssl.verifyhost) {
1633
2083
    retcode = verifyhost(conn, connssl->server_cert);
1638
2088
    }
1639
2089
  }
1640
2090
 
1641
 
  str = X509_NAME_oneline(X509_get_issuer_name(connssl->server_cert),
1642
 
                          NULL, 0);
1643
 
  if(!str) {
 
2091
  rc = x509_name_oneline(X509_get_issuer_name(connssl->server_cert),
 
2092
                         buffer, sizeof(buffer));
 
2093
  if(rc) {
1644
2094
    if(strict)
1645
2095
      failf(data, "SSL: couldn't get X509-issuer name!");
1646
2096
    retcode = CURLE_SSL_CONNECT_ERROR;
1647
2097
  }
1648
2098
  else {
1649
 
    infof(data, "\t issuer: %s\n", str);
1650
 
    CRYPTO_free(str);
 
2099
    infof(data, "\t issuer: %s\n", buffer);
1651
2100
 
1652
2101
    /* We could do all sorts of certificate verification stuff here before
1653
2102
       deallocating the certificate. */
1654
2103
 
 
2104
    /* e.g. match issuer name with provided issuer certificate */
 
2105
    if (data->set.str[STRING_SSL_ISSUERCERT]) {
 
2106
      if (! (fp=fopen(data->set.str[STRING_SSL_ISSUERCERT],"r"))) {
 
2107
        if (strict)
 
2108
          failf(data, "SSL: Unable to open issuer cert (%s)\n",
 
2109
                data->set.str[STRING_SSL_ISSUERCERT]);
 
2110
        X509_free(connssl->server_cert);
 
2111
        connssl->server_cert = NULL;
 
2112
        return CURLE_SSL_ISSUER_ERROR;
 
2113
      }
 
2114
      issuer = PEM_read_X509(fp,NULL,ZERO_NULL,NULL);
 
2115
      if (!issuer) {
 
2116
        if (strict)
 
2117
          failf(data, "SSL: Unable to read issuer cert (%s)\n",
 
2118
                data->set.str[STRING_SSL_ISSUERCERT]);
 
2119
        X509_free(connssl->server_cert);
 
2120
        X509_free(issuer);
 
2121
        fclose(fp);
 
2122
        return CURLE_SSL_ISSUER_ERROR;
 
2123
      }
 
2124
      fclose(fp);
 
2125
      if (X509_check_issued(issuer,connssl->server_cert) != X509_V_OK) {
 
2126
        if (strict)
 
2127
          failf(data, "SSL: Certificate issuer check failed (%s)\n",
 
2128
                data->set.str[STRING_SSL_ISSUERCERT]);
 
2129
        X509_free(connssl->server_cert);
 
2130
        X509_free(issuer);
 
2131
        connssl->server_cert = NULL;
 
2132
        return CURLE_SSL_ISSUER_ERROR;
 
2133
      }
 
2134
      infof(data, "\t SSL certificate issuer check ok (%s)\n",
 
2135
            data->set.str[STRING_SSL_ISSUERCERT]);
 
2136
      X509_free(issuer);
 
2137
    }
 
2138
 
1655
2139
    lerr = data->set.ssl.certverifyresult=
1656
2140
      SSL_get_verify_result(connssl->handle);
1657
2141
    if(data->set.ssl.certverifyresult != X509_V_OK) {
1658
2142
      if(data->set.ssl.verifypeer) {
1659
2143
        /* We probably never reach this, because SSL_connect() will fail
1660
 
           and we return earlyer if verifypeer is set? */
 
2144
           and we return earlier if verifypeer is set? */
1661
2145
        if(strict)
1662
2146
          failf(data, "SSL certificate verify result: %s (%ld)",
1663
2147
                X509_verify_cert_error_string(lerr), lerr);
1664
2148
        retcode = CURLE_PEER_FAILED_VERIFICATION;
1665
2149
      }
1666
2150
      else
1667
 
        infof(data, "SSL certificate verify result: %s (%ld),"
 
2151
        infof(data, "\t SSL certificate verify result: %s (%ld),"
1668
2152
              " continuing anyway.\n",
1669
2153
              X509_verify_cert_error_string(lerr), lerr);
1670
2154
    }
1671
2155
    else
1672
 
      infof(data, "SSL certificate verify ok.\n");
 
2156
      infof(data, "\t SSL certificate verify ok.\n");
1673
2157
  }
1674
2158
 
1675
2159
  X509_free(connssl->server_cert);
1784
2268
    if(connssl->connecting_state == ssl_connect_2_reading
1785
2269
        || connssl->connecting_state == ssl_connect_2_writing) {
1786
2270
 
1787
 
      int writefd = ssl_connect_2_writing==
 
2271
      curl_socket_t writefd = ssl_connect_2_writing==
1788
2272
        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1789
 
      int readfd = ssl_connect_2_reading==
 
2273
      curl_socket_t readfd = ssl_connect_2_reading==
1790
2274
        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1791
2275
 
1792
2276
      while(1) {
1865
2349
  return CURLE_OK;
1866
2350
}
1867
2351
 
 
2352
bool Curl_ossl_data_pending(const struct connectdata *conn,
 
2353
                            int connindex)
 
2354
{
 
2355
  if(conn->ssl[connindex].handle)
 
2356
    /* SSL is in use */
 
2357
    return (bool)(0 != SSL_pending(conn->ssl[connindex].handle));
 
2358
  else
 
2359
    return FALSE;
 
2360
}
 
2361
 
1868
2362
/* return number of sent (non-SSL) bytes */
1869
2363
ssize_t Curl_ossl_send(struct connectdata *conn,
1870
2364
                       int sockindex,