~ubuntu-branches/ubuntu/maverick/tomcat6/maverick-updates

« back to all changes in this revision

Viewing changes to native/connector/src/sslcontext.c

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2010-01-23 19:40:38 UTC
  • mfrom: (2.2.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100123194038-0tnrf6kiy0wrjrw9
Tags: 6.0.20-dfsg1-1
* Fix debian/orig-tar.sh to exclude binary only standard.jar and jstl.jar.
  (Closes: #528119)
* Upload a cleaned tarball.
* Add ${misc:Depends} in debian/control.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Licensed to the Apache Software Foundation (ASF) under one or more
2
 
 * contributor license agreements.  See the NOTICE file distributed with
3
 
 * this work for additional information regarding copyright ownership.
4
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
5
 
 * (the "License"); you may not use this file except in compliance with
6
 
 * the License.  You may obtain a copy of the License at
7
 
 *
8
 
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 
 *
10
 
 * Unless required by applicable law or agreed to in writing, software
11
 
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 
 * See the License for the specific language governing permissions and
14
 
 * limitations under the License.
15
 
 */
16
 
 
17
 
/** SSL Context wrapper
18
 
 *
19
 
 * @author Mladen Turk
20
 
 * @version $Revision: 607875 $, $Date: 2008-01-01 18:33:12 +0100 (Tue, 01 Jan 2008) $
21
 
 */
22
 
 
23
 
#include "tcn.h"
24
 
 
25
 
#include "apr_file_io.h"
26
 
#include "apr_thread_mutex.h"
27
 
#include "apr_poll.h"
28
 
 
29
 
#ifdef HAVE_OPENSSL
30
 
#include "ssl_private.h"
31
 
 
32
 
static apr_status_t ssl_context_cleanup(void *data)
33
 
{
34
 
    tcn_ssl_ctxt_t *c = (tcn_ssl_ctxt_t *)data;
35
 
    if (c) {
36
 
        int i;
37
 
        if (c->crl)
38
 
            X509_STORE_free(c->crl);
39
 
        c->crl = NULL;
40
 
        if (c->ctx)
41
 
            SSL_CTX_free(c->ctx);
42
 
        c->ctx = NULL;
43
 
        for (i = 0; i < SSL_AIDX_MAX; i++) {
44
 
            if (c->certs[i]) {
45
 
                X509_free(c->certs[i]);
46
 
                c->certs[i] = NULL;
47
 
            }
48
 
            if (c->keys[i]) {
49
 
                EVP_PKEY_free(c->keys[i]);
50
 
                c->keys[i] = NULL;
51
 
            }
52
 
        }
53
 
        if (c->bio_is) {
54
 
            SSL_BIO_close(c->bio_is);
55
 
            c->bio_is = NULL;
56
 
        }
57
 
        if (c->bio_os) {
58
 
            SSL_BIO_close(c->bio_os);
59
 
            c->bio_os = NULL;
60
 
        }
61
 
    }
62
 
    return APR_SUCCESS;
63
 
}
64
 
 
65
 
/* Initialize server context */
66
 
TCN_IMPLEMENT_CALL(jlong, SSLContext, make)(TCN_STDARGS, jlong pool,
67
 
                                            jint protocol, jint mode)
68
 
{
69
 
    apr_pool_t *p = J2P(pool, apr_pool_t *);
70
 
    tcn_ssl_ctxt_t *c = NULL;
71
 
    SSL_CTX *ctx = NULL;
72
 
    UNREFERENCED(o);
73
 
 
74
 
    switch (protocol) {
75
 
        case SSL_PROTOCOL_SSLV2:
76
 
        case SSL_PROTOCOL_SSLV2 | SSL_PROTOCOL_TLSV1:
77
 
            if (mode == SSL_MODE_CLIENT)
78
 
                ctx = SSL_CTX_new(SSLv2_client_method());
79
 
            else if (mode == SSL_MODE_SERVER)
80
 
                ctx = SSL_CTX_new(SSLv2_server_method());
81
 
            else
82
 
                ctx = SSL_CTX_new(SSLv2_method());
83
 
        break;
84
 
        case SSL_PROTOCOL_SSLV3:
85
 
        case SSL_PROTOCOL_SSLV3 | SSL_PROTOCOL_TLSV1:
86
 
            if (mode == SSL_MODE_CLIENT)
87
 
                ctx = SSL_CTX_new(SSLv3_client_method());
88
 
            else if (mode == SSL_MODE_SERVER)
89
 
                ctx = SSL_CTX_new(SSLv3_server_method());
90
 
            else
91
 
                ctx = SSL_CTX_new(SSLv3_method());
92
 
        break;
93
 
        case SSL_PROTOCOL_SSLV2 | SSL_PROTOCOL_SSLV3:
94
 
        case SSL_PROTOCOL_ALL:
95
 
            if (mode == SSL_MODE_CLIENT)
96
 
                ctx = SSL_CTX_new(SSLv23_client_method());
97
 
            else if (mode == SSL_MODE_SERVER)
98
 
                ctx = SSL_CTX_new(SSLv23_server_method());
99
 
            else
100
 
                ctx = SSL_CTX_new(SSLv23_method());
101
 
        break;
102
 
        case SSL_PROTOCOL_TLSV1:
103
 
            if (mode == SSL_MODE_CLIENT)
104
 
                ctx = SSL_CTX_new(TLSv1_client_method());
105
 
            else if (mode == SSL_MODE_SERVER)
106
 
                ctx = SSL_CTX_new(TLSv1_server_method());
107
 
            else
108
 
                ctx = SSL_CTX_new(TLSv1_method());
109
 
        break;
110
 
    }
111
 
    if (!ctx) {
112
 
        tcn_ThrowException(e, "Invalid Server SSL Protocol");
113
 
        goto init_failed;
114
 
    }
115
 
    if ((c = apr_pcalloc(p, sizeof(tcn_ssl_ctxt_t))) == NULL) {
116
 
        tcn_ThrowAPRException(e, apr_get_os_error());
117
 
        goto init_failed;
118
 
    }
119
 
 
120
 
    c->protocol = protocol;
121
 
    c->mode     = mode;
122
 
    c->ctx      = ctx;
123
 
    c->pool     = p;
124
 
    c->bio_os   = BIO_new(BIO_s_file());
125
 
    if (c->bio_os != NULL)
126
 
        BIO_set_fp(c->bio_os, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
127
 
    SSL_CTX_set_options(c->ctx, SSL_OP_ALL);
128
 
    if (!(protocol & SSL_PROTOCOL_SSLV2))
129
 
        SSL_CTX_set_options(c->ctx, SSL_OP_NO_SSLv2);
130
 
    if (!(protocol & SSL_PROTOCOL_SSLV3))
131
 
        SSL_CTX_set_options(c->ctx, SSL_OP_NO_SSLv3);
132
 
    if (!(protocol & SSL_PROTOCOL_TLSV1))
133
 
        SSL_CTX_set_options(c->ctx, SSL_OP_NO_TLSv1);
134
 
    /*
135
 
     * Configure additional context ingredients
136
 
     */
137
 
    SSL_CTX_set_options(c->ctx, SSL_OP_SINGLE_DH_USE);
138
 
 
139
 
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
140
 
    /*
141
 
     * Disallow a session from being resumed during a renegotiation,
142
 
     * so that an acceptable cipher suite can be negotiated.
143
 
     */
144
 
    SSL_CTX_set_options(c->ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
145
 
#endif
146
 
    /* Default session context id and cache size */
147
 
    SSL_CTX_sess_set_cache_size(c->ctx, SSL_DEFAULT_CACHE_SIZE);
148
 
    MD5((const unsigned char *)SSL_DEFAULT_VHOST_NAME,
149
 
        (unsigned long)(sizeof(SSL_DEFAULT_VHOST_NAME) - 1),
150
 
        &(c->context_id[0]));
151
 
    if (mode) {
152
 
        SSL_CTX_set_tmp_rsa_callback(c->ctx, SSL_callback_tmp_RSA);
153
 
        SSL_CTX_set_tmp_dh_callback(c->ctx,  SSL_callback_tmp_DH);
154
 
    }
155
 
    /* Set default Certificate verification level
156
 
     * and depth for the Client Authentication
157
 
     */
158
 
    c->verify_depth  = 1;
159
 
    c->verify_mode   = SSL_CVERIFY_UNSET;
160
 
    c->shutdown_type = SSL_SHUTDOWN_TYPE_UNSET;
161
 
 
162
 
    /* Set default password callback */
163
 
    SSL_CTX_set_default_passwd_cb(c->ctx, (pem_password_cb *)SSL_password_callback);
164
 
    SSL_CTX_set_default_passwd_cb_userdata(c->ctx, (void *)(&tcn_password_callback));
165
 
    /*
166
 
     * Let us cleanup the ssl context when the pool is destroyed
167
 
     */
168
 
    apr_pool_cleanup_register(p, (const void *)c,
169
 
                              ssl_context_cleanup,
170
 
                              apr_pool_cleanup_null);
171
 
 
172
 
    return P2J(c);
173
 
init_failed:
174
 
    return 0;
175
 
}
176
 
 
177
 
TCN_IMPLEMENT_CALL(jint, SSLContext, free)(TCN_STDARGS, jlong ctx)
178
 
{
179
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
180
 
    UNREFERENCED_STDARGS;
181
 
    TCN_ASSERT(ctx != 0);
182
 
    /* Run and destroy the cleanup callback */
183
 
    return apr_pool_cleanup_run(c->pool, c, ssl_context_cleanup);
184
 
}
185
 
 
186
 
TCN_IMPLEMENT_CALL(void, SSLContext, setContextId)(TCN_STDARGS, jlong ctx,
187
 
                                                   jstring id)
188
 
{
189
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
190
 
    TCN_ALLOC_CSTRING(id);
191
 
 
192
 
    TCN_ASSERT(ctx != 0);
193
 
    UNREFERENCED(o);
194
 
    if (J2S(id)) {
195
 
        MD5((const unsigned char *)J2S(id),
196
 
            (unsigned long)strlen(J2S(id)),
197
 
            &(c->context_id[0]));
198
 
    }
199
 
    TCN_FREE_CSTRING(id);
200
 
}
201
 
 
202
 
TCN_IMPLEMENT_CALL(void, SSLContext, setBIO)(TCN_STDARGS, jlong ctx,
203
 
                                             jlong bio, jint dir)
204
 
{
205
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
206
 
    BIO *bio_handle   = J2P(bio, BIO *);
207
 
 
208
 
    UNREFERENCED_STDARGS;
209
 
    TCN_ASSERT(ctx != 0);
210
 
    if (dir == 0) {
211
 
        if (c->bio_os && c->bio_os != bio_handle)
212
 
            SSL_BIO_close(c->bio_os);
213
 
        c->bio_os = bio_handle;
214
 
    }
215
 
    else if (dir == 1) {
216
 
        if (c->bio_is && c->bio_is != bio_handle)
217
 
            SSL_BIO_close(c->bio_is);
218
 
        c->bio_is = bio_handle;
219
 
    }
220
 
    else
221
 
        return;
222
 
    SSL_BIO_doref(bio_handle);
223
 
}
224
 
 
225
 
TCN_IMPLEMENT_CALL(void, SSLContext, setOptions)(TCN_STDARGS, jlong ctx,
226
 
                                                 jint opt)
227
 
{
228
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
229
 
 
230
 
    UNREFERENCED_STDARGS;
231
 
    TCN_ASSERT(ctx != 0);
232
 
    SSL_CTX_set_options(c->ctx, opt);
233
 
}
234
 
 
235
 
TCN_IMPLEMENT_CALL(void, SSLContext, setQuietShutdown)(TCN_STDARGS, jlong ctx,
236
 
                                                       jboolean mode)
237
 
{
238
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
239
 
 
240
 
    UNREFERENCED_STDARGS;
241
 
    TCN_ASSERT(ctx != 0);
242
 
    SSL_CTX_set_quiet_shutdown(c->ctx, mode ? 1 : 0);
243
 
}
244
 
 
245
 
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCipherSuite)(TCN_STDARGS, jlong ctx,
246
 
                                                         jstring ciphers)
247
 
{
248
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
249
 
    TCN_ALLOC_CSTRING(ciphers);
250
 
    jboolean rv = JNI_TRUE;
251
 
 
252
 
    UNREFERENCED(o);
253
 
    TCN_ASSERT(ctx != 0);
254
 
    if (!J2S(ciphers))
255
 
        return JNI_FALSE;
256
 
 
257
 
    if (!SSL_CTX_set_cipher_list(c->ctx, J2S(ciphers))) {
258
 
        char err[256];
259
 
        ERR_error_string(ERR_get_error(), err);
260
 
        tcn_Throw(e, "Unable to configure permitted SSL ciphers (%s)", err);
261
 
        rv = JNI_FALSE;
262
 
    }
263
 
    TCN_FREE_CSTRING(ciphers);
264
 
    return rv;
265
 
}
266
 
 
267
 
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCARevocation)(TCN_STDARGS, jlong ctx,
268
 
                                                          jstring file,
269
 
                                                          jstring path)
270
 
{
271
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
272
 
    TCN_ALLOC_CSTRING(file);
273
 
    TCN_ALLOC_CSTRING(path);
274
 
    jboolean rv = JNI_FALSE;
275
 
    X509_LOOKUP *lookup;
276
 
    char err[256];
277
 
 
278
 
    UNREFERENCED(o);
279
 
    TCN_ASSERT(ctx != 0);
280
 
    if (J2S(file) == NULL && J2S(path) == NULL)
281
 
        return JNI_FALSE;
282
 
 
283
 
    if (!c->crl) {
284
 
        if ((c->crl = X509_STORE_new()) == NULL)
285
 
            goto cleanup;
286
 
    }
287
 
    if (J2S(file)) {
288
 
        lookup = X509_STORE_add_lookup(c->crl, X509_LOOKUP_file());
289
 
        if (lookup == NULL) {
290
 
            ERR_error_string(ERR_get_error(), err);
291
 
            X509_STORE_free(c->crl);
292
 
            c->crl = NULL;
293
 
            tcn_Throw(e, "Lookup failed for file %s (%s)", J2S(file), err);
294
 
            goto cleanup;
295
 
        }
296
 
        X509_LOOKUP_load_file(lookup, J2S(file), X509_FILETYPE_PEM);
297
 
    }
298
 
    if (J2S(path)) {
299
 
        lookup = X509_STORE_add_lookup(c->crl, X509_LOOKUP_hash_dir());
300
 
        if (lookup == NULL) {
301
 
            ERR_error_string(ERR_get_error(), err);
302
 
            X509_STORE_free(c->crl);
303
 
            c->crl = NULL;
304
 
            tcn_Throw(e, "Lookup failed for path %s (%s)", J2S(file), err);
305
 
            goto cleanup;
306
 
        }
307
 
        X509_LOOKUP_add_dir(lookup, J2S(path), X509_FILETYPE_PEM);
308
 
    }
309
 
    rv = JNI_TRUE;
310
 
cleanup:
311
 
    TCN_FREE_CSTRING(file);
312
 
    TCN_FREE_CSTRING(path);
313
 
    return rv;
314
 
}
315
 
 
316
 
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateChainFile)(TCN_STDARGS, jlong ctx,
317
 
                                                                  jstring file,
318
 
                                                                  jboolean skipfirst)
319
 
{
320
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
321
 
    jboolean rv = JNI_FALSE;
322
 
    TCN_ALLOC_CSTRING(file);
323
 
 
324
 
    UNREFERENCED(o);
325
 
    TCN_ASSERT(ctx != 0);
326
 
    if (!J2S(file))
327
 
        return JNI_FALSE;
328
 
    if (SSL_CTX_use_certificate_chain(c->ctx, J2S(file), skipfirst) > 0)
329
 
        rv = JNI_TRUE;
330
 
    TCN_FREE_CSTRING(file);
331
 
    return rv;
332
 
}
333
 
 
334
 
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCACertificate)(TCN_STDARGS,
335
 
                                                           jlong ctx,
336
 
                                                           jstring file,
337
 
                                                           jstring path)
338
 
{
339
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
340
 
    jboolean rv = JNI_TRUE;
341
 
    TCN_ALLOC_CSTRING(file);
342
 
    TCN_ALLOC_CSTRING(path);
343
 
 
344
 
    UNREFERENCED(o);
345
 
    TCN_ASSERT(ctx != 0);
346
 
    if (file == NULL && path == NULL)
347
 
        return JNI_FALSE;
348
 
 
349
 
   /*
350
 
     * Configure Client Authentication details
351
 
     */
352
 
    if (!SSL_CTX_load_verify_locations(c->ctx,
353
 
                                       J2S(file), J2S(path))) {
354
 
        char err[256];
355
 
        ERR_error_string(ERR_get_error(), err);
356
 
        tcn_Throw(e, "Unable to configure locations "
357
 
                  "for client authentication (%s)", err);
358
 
        rv = JNI_FALSE;
359
 
        goto cleanup;
360
 
    }
361
 
    c->store = SSL_CTX_get_cert_store(c->ctx);
362
 
    if (c->mode) {
363
 
        STACK_OF(X509_NAME) *ca_certs;
364
 
        c->ca_certs++;
365
 
        ca_certs = SSL_CTX_get_client_CA_list(c->ctx);
366
 
        if (ca_certs == NULL) {
367
 
            SSL_load_client_CA_file(J2S(file));
368
 
            if (ca_certs != NULL)
369
 
                SSL_CTX_set_client_CA_list(c->ctx, (STACK *)ca_certs);
370
 
        }
371
 
        else {
372
 
            if (!SSL_add_file_cert_subjects_to_stack((STACK *)ca_certs, J2S(file)))
373
 
                ca_certs = NULL;
374
 
        }
375
 
        if (ca_certs == NULL && c->verify_mode == SSL_CVERIFY_REQUIRE) {
376
 
            /*
377
 
             * Give a warning when no CAs were configured but client authentication
378
 
             * should take place. This cannot work.
379
 
            */
380
 
            BIO_printf(c->bio_os,
381
 
                        "[WARN] Oops, you want to request client "
382
 
                        "authentication, but no CAs are known for "
383
 
                        "verification!?");
384
 
        }
385
 
    }
386
 
cleanup:
387
 
    TCN_FREE_CSTRING(file);
388
 
    TCN_FREE_CSTRING(path);
389
 
    return rv;
390
 
}
391
 
 
392
 
TCN_IMPLEMENT_CALL(void, SSLContext, setShutdownType)(TCN_STDARGS, jlong ctx,
393
 
                                                      jint type)
394
 
{
395
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
396
 
 
397
 
    UNREFERENCED_STDARGS;
398
 
    TCN_ASSERT(ctx != 0);
399
 
    c->shutdown_type = type;
400
 
}
401
 
 
402
 
TCN_IMPLEMENT_CALL(void, SSLContext, setVerify)(TCN_STDARGS, jlong ctx,
403
 
                                                jint level, jint depth)
404
 
{
405
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
406
 
    int verify = SSL_VERIFY_NONE;
407
 
 
408
 
    UNREFERENCED(o);
409
 
    TCN_ASSERT(ctx != 0);
410
 
    c->verify_mode = level;
411
 
 
412
 
    if (c->verify_mode == SSL_CVERIFY_UNSET)
413
 
        c->verify_mode = SSL_CVERIFY_NONE;
414
 
    if (depth > 0)
415
 
        c->verify_depth = depth;
416
 
    /*
417
 
     *  Configure callbacks for SSL context
418
 
     */
419
 
    if (c->verify_mode == SSL_CVERIFY_REQUIRE)
420
 
        verify |= SSL_VERIFY_PEER_STRICT;
421
 
    if ((c->verify_mode == SSL_CVERIFY_OPTIONAL) ||
422
 
        (c->verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
423
 
        verify |= SSL_VERIFY_PEER;
424
 
    if (!c->store) {
425
 
        if (SSL_CTX_set_default_verify_paths(c->ctx)) {
426
 
            c->store = SSL_CTX_get_cert_store(c->ctx);
427
 
            X509_STORE_set_flags(c->store, 0);
428
 
        }
429
 
        else {
430
 
            /* XXX: See if this is fatal */ 
431
 
        }
432
 
    }
433
 
 
434
 
    SSL_CTX_set_verify(c->ctx, verify, SSL_callback_SSL_verify);
435
 
}
436
 
 
437
 
static EVP_PKEY *load_pem_key(tcn_ssl_ctxt_t *c, const char *file)
438
 
{
439
 
    BIO *bio = NULL;
440
 
    EVP_PKEY *key = NULL;
441
 
    tcn_pass_cb_t *cb_data = c->cb_data;
442
 
    int i;
443
 
 
444
 
    if ((bio = BIO_new(BIO_s_file())) == NULL) {
445
 
        return NULL;
446
 
    }
447
 
    if (BIO_read_filename(bio, file) <= 0) {
448
 
        BIO_free(bio);
449
 
        return NULL;
450
 
    }
451
 
    if (!cb_data)
452
 
        cb_data = &tcn_password_callback;
453
 
    for (i = 0; i < 3; i++) {
454
 
        key = PEM_read_bio_PrivateKey(bio, NULL,
455
 
                    (pem_password_cb *)SSL_password_callback,
456
 
                    (void *)cb_data);
457
 
        if (key)
458
 
            break;
459
 
        cb_data->password[0] = '\0';
460
 
        BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL);
461
 
    }
462
 
    BIO_free(bio);
463
 
    return key;
464
 
}
465
 
 
466
 
static X509 *load_pem_cert(tcn_ssl_ctxt_t *c, const char *file)
467
 
{
468
 
    BIO *bio = NULL;
469
 
    X509 *cert = NULL;
470
 
    tcn_pass_cb_t *cb_data = c->cb_data;
471
 
    int i;
472
 
 
473
 
    if ((bio = BIO_new(BIO_s_file())) == NULL) {
474
 
        return NULL;
475
 
    }
476
 
    if (BIO_read_filename(bio, file) <= 0) {
477
 
        BIO_free(bio);
478
 
        return NULL;
479
 
    }
480
 
    for (i = 0; i < 3; i++) {
481
 
        cert = PEM_read_bio_X509_AUX(bio, NULL,
482
 
                    (pem_password_cb *)SSL_password_callback,
483
 
                    (void *)cb_data);
484
 
        if (cert)
485
 
            break;
486
 
        cb_data->password[0] = '\0';
487
 
        BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL);
488
 
    }
489
 
    BIO_free(bio);
490
 
    return cert;
491
 
}
492
 
 
493
 
TCN_IMPLEMENT_CALL(void, SSLContext, setRandom)(TCN_STDARGS, jlong ctx,
494
 
                                                jstring file)
495
 
{
496
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
497
 
    TCN_ALLOC_CSTRING(file);    
498
 
 
499
 
    TCN_ASSERT(ctx != 0);
500
 
    UNREFERENCED(o);
501
 
    if (J2S(file))
502
 
        c->rand_file = apr_pstrdup(c->pool, J2S(file));
503
 
    TCN_FREE_CSTRING(file);
504
 
}
505
 
 
506
 
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificate)(TCN_STDARGS, jlong ctx,
507
 
                                                         jstring cert, jstring key,
508
 
                                                         jstring password, jint idx)
509
 
{
510
 
    tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
511
 
    jboolean rv = JNI_TRUE;
512
 
    TCN_ALLOC_CSTRING(cert);
513
 
    TCN_ALLOC_CSTRING(key);
514
 
    TCN_ALLOC_CSTRING(password);
515
 
    const char *key_file, *cert_file;
516
 
    char err[256];
517
 
 
518
 
    UNREFERENCED(o);
519
 
    TCN_ASSERT(ctx != 0);
520
 
 
521
 
    if (idx < 0 || idx >= SSL_AIDX_MAX) {
522
 
        /* TODO: Throw something */
523
 
        rv = JNI_FALSE;
524
 
        goto cleanup;
525
 
    }
526
 
    if (J2S(password)) {
527
 
        if (!c->cb_data)
528
 
            c->cb_data = &tcn_password_callback;
529
 
        strncpy(c->cb_data->password, J2S(password), SSL_MAX_PASSWORD_LEN);
530
 
        c->cb_data->password[SSL_MAX_PASSWORD_LEN-1] = '\0';
531
 
    }
532
 
    key_file  = J2S(key);
533
 
    cert_file = J2S(cert);
534
 
    if (!key_file)
535
 
        key_file = cert_file;
536
 
    if (!key_file) {
537
 
        tcn_Throw(e, "No Certificate file specified or invalid file format");
538
 
        rv = JNI_FALSE;
539
 
        goto cleanup;
540
 
    }
541
 
    if ((c->keys[idx] = load_pem_key(c, key_file)) == NULL) {
542
 
        ERR_error_string(ERR_get_error(), err);
543
 
        tcn_Throw(e, "Unable to load certificate key %s (%s)",
544
 
                  key_file, err);
545
 
        rv = JNI_FALSE;
546
 
        goto cleanup;
547
 
    }
548
 
    if ((c->certs[idx] = load_pem_cert(c, cert_file)) == NULL) {
549
 
        ERR_error_string(ERR_get_error(), err);
550
 
        tcn_Throw(e, "Unable to load certificate %s (%s)",
551
 
                  cert_file, err);
552
 
        rv = JNI_FALSE;
553
 
        goto cleanup;
554
 
    }
555
 
    if (SSL_CTX_use_certificate(c->ctx, c->certs[idx]) <= 0) {
556
 
        ERR_error_string(ERR_get_error(), err);
557
 
        tcn_Throw(e, "Error setting certificate (%s)", err);
558
 
        rv = JNI_FALSE;
559
 
        goto cleanup;
560
 
    }
561
 
    if (SSL_CTX_use_PrivateKey(c->ctx, c->keys[idx]) <= 0) {
562
 
        ERR_error_string(ERR_get_error(), err);
563
 
        tcn_Throw(e, "Error setting private key (%s)", err);
564
 
        rv = JNI_FALSE;
565
 
        goto cleanup;
566
 
    }
567
 
    if (SSL_CTX_check_private_key(c->ctx) <= 0) {
568
 
        ERR_error_string(ERR_get_error(), err);
569
 
        tcn_Throw(e, "Private key does not match the certificate public key (%s)",
570
 
                  err);
571
 
        rv = JNI_FALSE;
572
 
        goto cleanup;
573
 
    }
574
 
cleanup:
575
 
    TCN_FREE_CSTRING(cert);
576
 
    TCN_FREE_CSTRING(key);
577
 
    TCN_FREE_CSTRING(password);
578
 
    return rv;
579
 
}
580
 
 
581
 
#else
582
 
/* OpenSSL is not supported.
583
 
 * Create empty stubs.
584
 
 */
585
 
 
586
 
TCN_IMPLEMENT_CALL(jlong, SSLContext, make)(TCN_STDARGS, jlong pool,
587
 
                                            jint protocol, jint mode)
588
 
{
589
 
    UNREFERENCED_STDARGS;
590
 
    UNREFERENCED(pool);
591
 
    UNREFERENCED(protocol);
592
 
    UNREFERENCED(mode);
593
 
    return 0;
594
 
}
595
 
 
596
 
TCN_IMPLEMENT_CALL(jint, SSLContext, free)(TCN_STDARGS, jlong ctx)
597
 
{
598
 
    UNREFERENCED_STDARGS;
599
 
    UNREFERENCED(ctx);
600
 
    return APR_ENOTIMPL;
601
 
}
602
 
 
603
 
TCN_IMPLEMENT_CALL(void, SSLContext, setContextId)(TCN_STDARGS, jlong ctx,
604
 
                                                   jstring id)
605
 
{
606
 
    UNREFERENCED_STDARGS;
607
 
    UNREFERENCED(ctx);
608
 
    UNREFERENCED(id);
609
 
}
610
 
 
611
 
TCN_IMPLEMENT_CALL(void, SSLContext, setBIO)(TCN_STDARGS, jlong ctx,
612
 
                                             jlong bio, jint dir)
613
 
{
614
 
    UNREFERENCED_STDARGS;
615
 
    UNREFERENCED(ctx);
616
 
    UNREFERENCED(bio);
617
 
    UNREFERENCED(dir);
618
 
}
619
 
 
620
 
TCN_IMPLEMENT_CALL(void, SSLContext, setOptions)(TCN_STDARGS, jlong ctx,
621
 
                                                 jint opt)
622
 
{
623
 
    UNREFERENCED_STDARGS;
624
 
    UNREFERENCED(ctx);
625
 
    UNREFERENCED(opt);
626
 
}
627
 
 
628
 
TCN_IMPLEMENT_CALL(void, SSLContext, setQuietShutdown)(TCN_STDARGS, jlong ctx,
629
 
                                                       jboolean mode)
630
 
{
631
 
    UNREFERENCED_STDARGS;
632
 
    UNREFERENCED(ctx);
633
 
    UNREFERENCED(mode);
634
 
}
635
 
 
636
 
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCipherSuite)(TCN_STDARGS, jlong ctx,
637
 
                                                         jstring ciphers)
638
 
{
639
 
    UNREFERENCED_STDARGS;
640
 
    UNREFERENCED(ctx);
641
 
    UNREFERENCED(ciphers);
642
 
    return JNI_FALSE;
643
 
}
644
 
 
645
 
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCARevocation)(TCN_STDARGS, jlong ctx,
646
 
                                                          jstring file,
647
 
                                                          jstring path)
648
 
{
649
 
    UNREFERENCED_STDARGS;
650
 
    UNREFERENCED(ctx);
651
 
    UNREFERENCED(file);
652
 
    UNREFERENCED(path);
653
 
    return JNI_FALSE;
654
 
}
655
 
 
656
 
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateChainFile)(TCN_STDARGS, jlong ctx,
657
 
                                                                  jstring file,
658
 
                                                                  jboolean skipfirst)
659
 
{
660
 
    UNREFERENCED_STDARGS;
661
 
    UNREFERENCED(ctx);
662
 
    UNREFERENCED(file);
663
 
    UNREFERENCED(skipfirst);
664
 
    return JNI_FALSE;
665
 
}
666
 
 
667
 
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCACertificate)(TCN_STDARGS,
668
 
                                                           jlong ctx,
669
 
                                                           jstring file,
670
 
                                                           jstring path)
671
 
{
672
 
    UNREFERENCED_STDARGS;
673
 
    UNREFERENCED(ctx);
674
 
    UNREFERENCED(file);
675
 
    UNREFERENCED(path);
676
 
    return JNI_FALSE;
677
 
}
678
 
 
679
 
TCN_IMPLEMENT_CALL(void, SSLContext, setShutdownType)(TCN_STDARGS, jlong ctx,
680
 
                                                      jint type)
681
 
{
682
 
    UNREFERENCED_STDARGS;
683
 
    UNREFERENCED(ctx);
684
 
    UNREFERENCED(type);
685
 
}
686
 
 
687
 
TCN_IMPLEMENT_CALL(void, SSLContext, setVerify)(TCN_STDARGS, jlong ctx,
688
 
                                                jint level, jint depth)
689
 
{
690
 
    UNREFERENCED_STDARGS;
691
 
    UNREFERENCED(ctx);
692
 
    UNREFERENCED(level);
693
 
    UNREFERENCED(depth);
694
 
}
695
 
 
696
 
TCN_IMPLEMENT_CALL(void, SSLContext, setRandom)(TCN_STDARGS, jlong ctx,
697
 
                                                jstring file)
698
 
{
699
 
    UNREFERENCED_STDARGS;
700
 
    UNREFERENCED(ctx);
701
 
    UNREFERENCED(file);
702
 
}
703
 
 
704
 
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificate)(TCN_STDARGS, jlong ctx,
705
 
                                                         jstring cert, jstring key,
706
 
                                                         jstring password, jint idx)
707
 
{
708
 
    UNREFERENCED_STDARGS;
709
 
    UNREFERENCED(ctx);
710
 
    UNREFERENCED(cert);
711
 
    UNREFERENCED(key);
712
 
    UNREFERENCED(password);
713
 
    UNREFERENCED(idx);
714
 
    return JNI_FALSE;
715
 
}
716
 
 
717
 
#endif