~ubuntu-branches/ubuntu/trusty/aria2/trusty-proposed

« back to all changes in this revision

Viewing changes to src/LibsslTLSContext.cc

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry
  • Date: 2013-12-16 18:41:03 UTC
  • mfrom: (2.5.21 sid)
  • Revision ID: package-import@ubuntu.com-20131216184103-xzah3019zwut429g
Tags: 1.18.1-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
/* copyright --> */
35
35
#include "LibsslTLSContext.h"
36
36
 
 
37
#include <sstream>
 
38
 
37
39
#include <openssl/err.h>
 
40
#include <openssl/pkcs12.h>
 
41
#include <openssl/bio.h>
38
42
 
39
43
#include "LogFactory.h"
40
44
#include "Logger.h"
41
45
#include "fmt.h"
42
46
#include "message.h"
 
47
#include "BufferedFile.h"
 
48
 
 
49
namespace {
 
50
  struct bio_deleter {
 
51
    void operator()(BIO *b) {
 
52
      if (b) BIO_free(b);
 
53
    }
 
54
  };
 
55
  typedef std::unique_ptr<BIO, bio_deleter> bio_t;
 
56
  struct p12_deleter {
 
57
    void operator()(PKCS12 *p) {
 
58
      if (p) PKCS12_free(p);
 
59
    }
 
60
  };
 
61
  typedef std::unique_ptr<PKCS12, p12_deleter> p12_t;
 
62
  struct pkey_deleter {
 
63
    void operator()(EVP_PKEY *x) {
 
64
      if (x) EVP_PKEY_free(x);
 
65
    }
 
66
  };
 
67
  typedef std::unique_ptr<EVP_PKEY, pkey_deleter> pkey_t;
 
68
  struct x509_deleter {
 
69
    void operator()(X509 *x) {
 
70
      if (x) X509_free(x);
 
71
    }
 
72
  };
 
73
  typedef std::unique_ptr<X509, x509_deleter> x509_t;
 
74
  struct x509_sk_deleter {
 
75
    void operator()(STACK_OF(X509) *x) {
 
76
      if (x) sk_X509_pop_free(x, X509_free);
 
77
    }
 
78
  };
 
79
  typedef std::unique_ptr<STACK_OF(X509), x509_sk_deleter> x509_sk_t;
 
80
} // namespace
43
81
 
44
82
namespace aria2 {
45
83
 
60
98
    good_ = false;
61
99
    A2_LOG_ERROR(fmt("SSL_CTX_new() failed. Cause: %s",
62
100
                     ERR_error_string(ERR_get_error(), 0)));
 
101
    return;
63
102
  }
64
103
  // Disable SSLv2 and enable all workarounds for buggy servers
65
104
  SSL_CTX_set_options(sslCtx_, SSL_OP_ALL | SSL_OP_NO_SSLv2
73
112
  /* keep memory usage low */
74
113
  SSL_CTX_set_mode(sslCtx_, SSL_MODE_RELEASE_BUFFERS);
75
114
  #endif
 
115
  if(SSL_CTX_set_cipher_list(sslCtx_, "HIGH:!aNULL:!eNULL") == 0) {
 
116
    good_ = false;
 
117
    A2_LOG_ERROR(fmt("SSL_CTX_set_cipher_list() failed. Cause: %s",
 
118
                     ERR_error_string(ERR_get_error(), nullptr)));
 
119
  }
76
120
}
77
121
 
78
122
OpenSSLTLSContext::~OpenSSLTLSContext()
88
132
bool OpenSSLTLSContext::addCredentialFile(const std::string& certfile,
89
133
                                   const std::string& keyfile)
90
134
{
 
135
  if (keyfile.empty()) {
 
136
    return addP12CredentialFile(certfile);
 
137
  }
91
138
  if(SSL_CTX_use_PrivateKey_file(sslCtx_, keyfile.c_str(),
92
139
                                 SSL_FILETYPE_PEM) != 1) {
93
140
    A2_LOG_ERROR(fmt("Failed to load private key from %s. Cause: %s",
106
153
                  keyfile.c_str()));
107
154
  return true;
108
155
}
 
156
bool OpenSSLTLSContext::addP12CredentialFile(const std::string& p12file)
 
157
{
 
158
  std::stringstream ss;
 
159
  BufferedFile(p12file.c_str(), "rb").transfer(ss);
 
160
 
 
161
  auto data = ss.str();
 
162
  void *ptr = const_cast<char*>(data.c_str());
 
163
  size_t len = data.length();
 
164
  bio_t bio(BIO_new_mem_buf(ptr, len));
 
165
 
 
166
  if (!bio) {
 
167
    A2_LOG_ERROR("Failed to open PKCS12 file: no memory.");
 
168
    return false;
 
169
  }
 
170
  p12_t p12(d2i_PKCS12_bio(bio.get(), nullptr));
 
171
  if (!p12) {
 
172
    A2_LOG_ERROR(fmt("Failed to open PKCS12 file: %s. "
 
173
                     "If you meant to use PEM, you'll also have to specify "
 
174
                     "--rpc-private-key. See the manual.",
 
175
                     ERR_error_string(ERR_get_error(), nullptr)));
 
176
    return false;
 
177
  }
 
178
  EVP_PKEY *pkey;
 
179
  X509 *cert;
 
180
  STACK_OF(X509) *ca = 0;
 
181
  if (!PKCS12_parse(p12.get(), "", &pkey, &cert, &ca)) {
 
182
    A2_LOG_ERROR(fmt("Failed to parse PKCS12 file: %s. "
 
183
                     "If you meant to use PEM, you'll also have to specify "
 
184
                     "--rpc-private-key. See the manual.",
 
185
                     ERR_error_string(ERR_get_error(), nullptr)));
 
186
    return false;
 
187
  }
 
188
 
 
189
  pkey_t pkey_holder(pkey);
 
190
  x509_t cert_holder(cert);
 
191
  x509_sk_t ca_holder(ca);
 
192
 
 
193
  if (!pkey || !cert) {
 
194
    A2_LOG_ERROR(fmt("Failed to use PKCS12 file: no pkey or cert %s",
 
195
                     ERR_error_string(ERR_get_error(), nullptr)));
 
196
    return false;
 
197
  }
 
198
  if (!SSL_CTX_use_PrivateKey(sslCtx_, pkey)) {
 
199
    A2_LOG_ERROR(fmt("Failed to use PKCS12 file pkey: %s",
 
200
                      ERR_error_string(ERR_get_error(), nullptr)));
 
201
    return false;
 
202
  }
 
203
  if (!SSL_CTX_use_certificate(sslCtx_, cert)) {
 
204
    A2_LOG_ERROR(fmt("Failed to use PKCS12 file cert: %s",
 
205
                      ERR_error_string(ERR_get_error(), nullptr)));
 
206
    return false;
 
207
  }
 
208
  if (ca && sk_X509_num(ca) && !SSL_CTX_add_extra_chain_cert(sslCtx_, ca)) {
 
209
    A2_LOG_ERROR(fmt("Failed to use PKCS12 file chain: %s",
 
210
                      ERR_error_string(ERR_get_error(), nullptr)));
 
211
    return false;
 
212
  }
 
213
 
 
214
  A2_LOG_INFO("Using certificate and key from PKCS12 file");
 
215
  return true;
 
216
}
109
217
 
110
218
bool OpenSSLTLSContext::addSystemTrustedCACerts()
111
219
{