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#include "testutil.h"
18#include "apr.h"
19#include "apu.h"
20#include "apu_errno.h"
21#include "apr_pools.h"
22#include "apr_dso.h"
23#include "apr_crypto.h"
24#include "apr_strings.h"
25
26#if APU_HAVE_CRYPTO
27
28#define TEST_STRING "12345"
29#define ALIGNED_STRING "123456789012345"
30
31static const apr_crypto_driver_t *get_driver(abts_case *tc, apr_pool_t *pool,
32        const char *name, const char *params)
33{
34
35    const apr_crypto_driver_t *driver = NULL;
36    const apu_err_t *err = NULL;
37    apr_status_t rv;
38
39    rv = apr_crypto_init(pool);
40    ABTS_ASSERT(tc, "failed to init apr_crypto", rv == APR_SUCCESS);
41
42    rv = apr_crypto_get_driver(&driver, name, params, &err, pool);
43    if (APR_SUCCESS != rv && err) {
44        ABTS_NOT_IMPL(tc, err->msg);
45        return NULL;
46    }
47    if (APR_ENOTIMPL == rv) {
48        ABTS_NOT_IMPL(tc, (char *)driver);
49        return NULL;
50    }
51    ABTS_ASSERT(tc, "failed to apr_crypto_get_driver", rv == APR_SUCCESS);
52    ABTS_ASSERT(tc, "apr_crypto_get_driver returned NULL", driver != NULL);
53    if (!driver || rv) {
54        return NULL;
55    }
56
57    return driver;
58
59}
60
61static const apr_crypto_driver_t *get_nss_driver(abts_case *tc,
62        apr_pool_t *pool)
63{
64
65    /* initialise NSS */
66    return get_driver(tc, pool, "nss", "dir=data");
67
68}
69
70static const apr_crypto_driver_t *get_openssl_driver(abts_case *tc,
71        apr_pool_t *pool)
72{
73
74    return get_driver(tc, pool, "openssl", NULL);
75
76}
77
78static apr_crypto_t *make(abts_case *tc, apr_pool_t *pool,
79        const apr_crypto_driver_t *driver)
80{
81
82    apr_crypto_t *f = NULL;
83
84    if (!driver) {
85        return NULL;
86    }
87
88    /* get the context */
89    apr_crypto_make(&f, driver, "engine=openssl", pool);
90    ABTS_ASSERT(tc, "apr_crypto_make returned NULL", f != NULL);
91
92    return f;
93
94}
95
96static const apr_crypto_key_t *passphrase(abts_case *tc, apr_pool_t *pool,
97        const apr_crypto_driver_t *driver, const apr_crypto_t *f,
98        apr_crypto_block_key_type_e type, apr_crypto_block_key_mode_e mode,
99        int doPad, const char *description)
100{
101
102    apr_crypto_key_t *key = NULL;
103    const apu_err_t *result = NULL;
104    const char *pass = "secret";
105    const char *salt = "salt";
106    apr_status_t rv;
107
108    if (!f) {
109        return NULL;
110    }
111
112    /* init the passphrase */
113    rv = apr_crypto_passphrase(&key, NULL, pass, strlen(pass),
114            (unsigned char *) salt, strlen(salt), type, mode, doPad, 4096, f,
115            pool);
116    if (APR_ENOCIPHER == rv) {
117        apr_crypto_error(&result, f);
118        ABTS_NOT_IMPL(tc, apr_psprintf(pool,
119                        "skipped: %s %s passphrase return APR_ENOCIPHER: error %d: %s (%s)\n",
120                        description, apr_crypto_driver_name(driver), result->rc,
121                        result->reason ? result->reason : "", result->msg ? result->msg : ""));
122        return NULL;
123    }
124    else {
125        if (APR_SUCCESS != rv) {
126            apr_crypto_error(&result, f);
127            fprintf(stderr, "passphrase: %s %s native error %d: %s (%s)\n",
128                    description, apr_crypto_driver_name(driver), result->rc,
129                    result->reason ? result->reason : "",
130                    result->msg ? result->msg : "");
131        }
132        ABTS_ASSERT(tc, "apr_crypto_passphrase returned APR_ENOKEY", rv != APR_ENOKEY);
133        ABTS_ASSERT(tc, "apr_crypto_passphrase returned APR_EPADDING", rv != APR_EPADDING);
134        ABTS_ASSERT(tc, "apr_crypto_passphrase returned APR_EKEYTYPE", rv != APR_EKEYTYPE);
135        ABTS_ASSERT(tc, "failed to apr_crypto_passphrase", rv == APR_SUCCESS);
136        ABTS_ASSERT(tc, "apr_crypto_passphrase returned NULL context", key != NULL);
137    }
138    if (rv) {
139        return NULL;
140    }
141    return key;
142
143}
144
145static unsigned char *encrypt_block(abts_case *tc, apr_pool_t *pool,
146        const apr_crypto_driver_t *driver, const apr_crypto_t *f,
147        const apr_crypto_key_t *key, const unsigned char *in,
148        const apr_size_t inlen, unsigned char **cipherText,
149        apr_size_t *cipherTextLen, const unsigned char **iv,
150        apr_size_t *blockSize, const char *description)
151{
152
153    apr_crypto_block_t *block = NULL;
154    const apu_err_t *result = NULL;
155    apr_size_t len = 0;
156    apr_status_t rv;
157
158    if (!driver || !f || !key || !in) {
159        return NULL;
160    }
161
162    /* init the encryption */
163    rv = apr_crypto_block_encrypt_init(&block, iv, key, blockSize, pool);
164    if (APR_ENOTIMPL == rv) {
165        ABTS_NOT_IMPL(tc, "apr_crypto_block_encrypt_init returned APR_ENOTIMPL");
166    }
167    else {
168        if (APR_SUCCESS != rv) {
169            apr_crypto_error(&result, f);
170            fprintf(stderr, "encrypt_init: %s %s native error %d: %s (%s)\n",
171                    description, apr_crypto_driver_name(driver), result->rc,
172                    result->reason ? result->reason : "",
173                    result->msg ? result->msg : "");
174        }
175        ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_ENOKEY", rv != APR_ENOKEY);
176        ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_ENOIV", rv != APR_ENOIV);
177        ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_EKEYTYPE", rv != APR_EKEYTYPE);
178        ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_EKEYLENGTH", rv != APR_EKEYLENGTH);
179        ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt_init", rv == APR_SUCCESS);
180        ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned NULL context", block != NULL);
181    }
182    if (!block || rv) {
183        return NULL;
184    }
185
186    /* encrypt the block */
187    rv = apr_crypto_block_encrypt(cipherText, cipherTextLen, in, inlen, block);
188    if (APR_SUCCESS != rv) {
189        apr_crypto_error(&result, f);
190        fprintf(stderr, "encrypt: %s %s native error %d: %s (%s)\n",
191                description, apr_crypto_driver_name(driver), result->rc,
192                result->reason ? result->reason : "", result->msg ? result->msg
193                        : "");
194    }
195    ABTS_ASSERT(tc, "apr_crypto_block_encrypt returned APR_ECRYPT", rv != APR_ECRYPT);
196    ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt", rv == APR_SUCCESS);
197    ABTS_ASSERT(tc, "apr_crypto_block_encrypt failed to allocate buffer", *cipherText != NULL);
198    if (rv) {
199        return NULL;
200    }
201
202    /* finalise the encryption */
203    rv = apr_crypto_block_encrypt_finish(*cipherText + *cipherTextLen, &len,
204            block);
205    if (APR_SUCCESS != rv) {
206        apr_crypto_error(&result, f);
207        fprintf(stderr, "encrypt_finish: %s %s native error %d: %s (%s)\n",
208                description, apr_crypto_driver_name(driver), result->rc,
209                result->reason ? result->reason : "", result->msg ? result->msg
210                        : "");
211    }
212    ABTS_ASSERT(tc, "apr_crypto_block_encrypt_finish returned APR_ECRYPT", rv != APR_ECRYPT);
213    ABTS_ASSERT(tc, "apr_crypto_block_encrypt_finish returned APR_EPADDING", rv != APR_EPADDING);
214    ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt_finish", rv == APR_SUCCESS);
215    *cipherTextLen += len;
216    apr_crypto_block_cleanup(block);
217    if (rv) {
218        return NULL;
219    }
220
221    return *cipherText;
222
223}
224
225static unsigned char *decrypt_block(abts_case *tc, apr_pool_t *pool,
226        const apr_crypto_driver_t *driver, const apr_crypto_t *f,
227        const apr_crypto_key_t *key, unsigned char *cipherText,
228        apr_size_t cipherTextLen, unsigned char **plainText,
229        apr_size_t *plainTextLen, const unsigned char *iv,
230        apr_size_t *blockSize, const char *description)
231{
232
233    apr_crypto_block_t *block = NULL;
234    const apu_err_t *result = NULL;
235    apr_size_t len = 0;
236    apr_status_t rv;
237
238    if (!driver || !f || !key || !cipherText) {
239        return NULL;
240    }
241
242    /* init the decryption */
243    rv = apr_crypto_block_decrypt_init(&block, blockSize, iv, key, pool);
244    if (APR_ENOTIMPL == rv) {
245        ABTS_NOT_IMPL(tc, "apr_crypto_block_decrypt_init returned APR_ENOTIMPL");
246    }
247    else {
248        if (APR_SUCCESS != rv) {
249            apr_crypto_error(&result, f);
250            fprintf(stderr, "decrypt_init: %s %s native error %d: %s (%s)\n",
251                    description, apr_crypto_driver_name(driver), result->rc,
252                    result->reason ? result->reason : "",
253                    result->msg ? result->msg : "");
254        }
255        ABTS_ASSERT(tc, "apr_crypto_block_decrypt_init returned APR_ENOKEY", rv != APR_ENOKEY);
256        ABTS_ASSERT(tc, "apr_crypto_block_decrypt_init returned APR_ENOIV", rv != APR_ENOIV);
257        ABTS_ASSERT(tc, "apr_crypto_block_decrypt_init returned APR_EKEYTYPE", rv != APR_EKEYTYPE);
258        ABTS_ASSERT(tc, "apr_crypto_block_decrypt_init returned APR_EKEYLENGTH", rv != APR_EKEYLENGTH);
259        ABTS_ASSERT(tc, "failed to apr_crypto_block_decrypt_init", rv == APR_SUCCESS);
260        ABTS_ASSERT(tc, "apr_crypto_block_decrypt_init returned NULL context", block != NULL);
261    }
262    if (!block || rv) {
263        return NULL;
264    }
265
266    /* decrypt the block */
267    rv = apr_crypto_block_decrypt(plainText, plainTextLen, cipherText,
268            cipherTextLen, block);
269    if (APR_SUCCESS != rv) {
270        apr_crypto_error(&result, f);
271        fprintf(stderr, "decrypt: %s %s native error %d: %s (%s)\n",
272                description, apr_crypto_driver_name(driver), result->rc,
273                result->reason ? result->reason : "", result->msg ? result->msg
274                        : "");
275    }
276    ABTS_ASSERT(tc, "apr_crypto_block_decrypt returned APR_ECRYPT", rv != APR_ECRYPT);
277    ABTS_ASSERT(tc, "failed to apr_crypto_block_decrypt", rv == APR_SUCCESS);
278    ABTS_ASSERT(tc, "apr_crypto_block_decrypt failed to allocate buffer", *plainText != NULL);
279    if (rv) {
280        return NULL;
281    }
282
283    /* finalise the decryption */
284    rv = apr_crypto_block_decrypt_finish(*plainText + *plainTextLen, &len,
285            block);
286    if (APR_SUCCESS != rv) {
287        apr_crypto_error(&result, f);
288        fprintf(stderr, "decrypt_finish: %s %s native error %d: %s (%s)\n",
289                description, apr_crypto_driver_name(driver), result->rc,
290                result->reason ? result->reason : "", result->msg ? result->msg
291                        : "");
292    }
293    ABTS_ASSERT(tc, "apr_crypto_block_decrypt_finish returned APR_ECRYPT", rv != APR_ECRYPT);
294    ABTS_ASSERT(tc, "apr_crypto_block_decrypt_finish returned APR_EPADDING", rv != APR_EPADDING);
295    ABTS_ASSERT(tc, "failed to apr_crypto_block_decrypt_finish", rv == APR_SUCCESS);
296    if (rv) {
297        return NULL;
298    }
299
300    *plainTextLen += len;
301    apr_crypto_block_cleanup(block);
302
303    return *plainText;
304
305}
306
307/**
308 * Interoperability test.
309 *
310 * data must point at an array of two driver structures. Data will be encrypted
311 * with the first driver, and decrypted with the second.
312 *
313 * If the two drivers interoperate, the test passes.
314 */
315static void crypto_block_cross(abts_case *tc, apr_pool_t *pool,
316        const apr_crypto_driver_t **drivers,
317        const apr_crypto_block_key_type_e type,
318        const apr_crypto_block_key_mode_e mode, int doPad,
319        const unsigned char *in, apr_size_t inlen, const char *description)
320{
321    const apr_crypto_driver_t *driver1 = drivers[0];
322    const apr_crypto_driver_t *driver2 = drivers[1];
323    apr_crypto_t *f1 = NULL;
324    apr_crypto_t *f2 = NULL;
325    const apr_crypto_key_t *key1 = NULL;
326    const apr_crypto_key_t *key2 = NULL;
327
328    unsigned char *cipherText = NULL;
329    apr_size_t cipherTextLen = 0;
330    unsigned char *plainText = NULL;
331    apr_size_t plainTextLen = 0;
332    const unsigned char *iv = NULL;
333    apr_size_t blockSize = 0;
334
335    f1 = make(tc, pool, driver1);
336    f2 = make(tc, pool, driver2);
337    key1 = passphrase(tc, pool, driver1, f1, type, mode, doPad, description);
338    key2 = passphrase(tc, pool, driver2, f2, type, mode, doPad, description);
339
340    cipherText = encrypt_block(tc, pool, driver1, f1, key1, in, inlen,
341            &cipherText, &cipherTextLen, &iv, &blockSize, description);
342    plainText = decrypt_block(tc, pool, driver2, f2, key2, cipherText,
343            cipherTextLen, &plainText, &plainTextLen, iv, &blockSize,
344            description);
345
346    if (cipherText && plainText) {
347        if (memcmp(in, plainText, inlen)) {
348            fprintf(stderr, "cross mismatch: %s %s/%s\n", description,
349                    apr_crypto_driver_name(driver1), apr_crypto_driver_name(
350                            driver2));
351        }
352        ABTS_STR_EQUAL(tc, (char *)in, (char *)plainText);
353    }
354
355}
356
357/**
358 * Test initialisation.
359 */
360static void test_crypto_init(abts_case *tc, void *data)
361{
362    apr_pool_t *pool = NULL;
363    apr_status_t rv;
364
365    apr_pool_create(&pool, NULL);
366
367    rv = apr_crypto_init(pool);
368    ABTS_ASSERT(tc, "failed to init apr_crypto", rv == APR_SUCCESS);
369
370    apr_pool_destroy(pool);
371
372}
373
374/**
375 * Simple test of OpenSSL block crypt.
376 */
377static void test_crypto_block_openssl(abts_case *tc, void *data)
378{
379    apr_pool_t *pool = NULL;
380    const apr_crypto_driver_t *drivers[] = { NULL, NULL };
381
382    const unsigned char *in = (const unsigned char *) ALIGNED_STRING;
383    apr_size_t inlen = sizeof(ALIGNED_STRING);
384
385    apr_pool_create(&pool, NULL);
386    drivers[0] = get_openssl_driver(tc, pool);
387    drivers[1] = get_openssl_driver(tc, pool);
388    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0,
389            in, inlen, "KEY_3DES_192/MODE_CBC");
390    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 0,
391            in, inlen, "KEY_3DES_192/MODE_ECB");
392    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in,
393            inlen, "KEY_AES_256/MODE_CBC");
394    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in,
395            inlen, "KEY_AES_256/MODE_ECB");
396    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in,
397            inlen, "KEY_AES_192/MODE_CBC");
398    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in,
399            inlen, "KEY_AES_192/MODE_ECB");
400    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in,
401            inlen, "KEY_AES_128/MODE_CBC");
402    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in,
403            inlen, "KEY_AES_128/MODE_ECB");
404    apr_pool_destroy(pool);
405
406}
407
408/**
409 * Simple test of NSS block crypt.
410 */
411static void test_crypto_block_nss(abts_case *tc, void *data)
412{
413    apr_pool_t *pool = NULL;
414    const apr_crypto_driver_t *drivers[] = { NULL, NULL };
415
416    const unsigned char *in = (const unsigned char *) ALIGNED_STRING;
417    apr_size_t inlen = sizeof(ALIGNED_STRING);
418
419    apr_pool_create(&pool, NULL);
420    drivers[0] = get_nss_driver(tc, pool);
421    drivers[1] = get_nss_driver(tc, pool);
422    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0,
423            in, inlen, "KEY_3DES_192/MODE_CBC");
424    /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */
425    /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, "KEY_3DES_192/MODE_ECB"); */
426    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in,
427            inlen, "KEY_AES_256/MODE_CBC");
428    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in,
429            inlen, "KEY_AES_256/MODE_ECB");
430    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in,
431            inlen, "KEY_AES_192/MODE_CBC");
432    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in,
433            inlen, "KEY_AES_192/MODE_ECB");
434    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in,
435            inlen, "KEY_AES_128/MODE_CBC");
436    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in,
437            inlen, "KEY_AES_128/MODE_ECB");
438    apr_pool_destroy(pool);
439
440}
441
442/**
443 * Encrypt NSS, decrypt OpenSSL.
444 */
445static void test_crypto_block_nss_openssl(abts_case *tc, void *data)
446{
447    apr_pool_t *pool = NULL;
448    const apr_crypto_driver_t *drivers[] = { NULL, NULL };
449
450    const unsigned char *in = (const unsigned char *) ALIGNED_STRING;
451    apr_size_t inlen = sizeof(ALIGNED_STRING);
452
453    apr_pool_create(&pool, NULL);
454    drivers[0] = get_nss_driver(tc, pool);
455    drivers[1] = get_openssl_driver(tc, pool);
456
457    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0,
458            in, inlen, "KEY_3DES_192/MODE_CBC");
459
460    /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */
461    /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, "KEY_3DES_192/MODE_ECB"); */
462    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in,
463            inlen, "KEY_AES_256/MODE_CBC");
464    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in,
465            inlen, "KEY_AES_256/MODE_ECB");
466
467    /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that
468     * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be
469     * investigated.
470     */
471    /*
472     crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 0, in, inlen, "KEY_AES_192/MODE_CBC");
473     crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 0, in, inlen, "KEY_AES_192/MODE_ECB");
474     crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 0, in, inlen, "KEY_AES_128/MODE_CBC");
475     crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 0, in, inlen, "KEY_AES_128/MODE_ECB");
476     */
477    apr_pool_destroy(pool);
478
479}
480
481/**
482 * Encrypt OpenSSL, decrypt NSS.
483 */
484static void test_crypto_block_openssl_nss(abts_case *tc, void *data)
485{
486    apr_pool_t *pool = NULL;
487    const apr_crypto_driver_t *drivers[] = { NULL, NULL };
488
489    const unsigned char *in = (const unsigned char *) ALIGNED_STRING;
490    apr_size_t inlen = sizeof(ALIGNED_STRING);
491
492    apr_pool_create(&pool, NULL);
493    drivers[0] = get_openssl_driver(tc, pool);
494    drivers[1] = get_nss_driver(tc, pool);
495    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0,
496            in, inlen, "KEY_3DES_192/MODE_CBC");
497
498    /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */
499    /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, "KEY_3DES_192/MODE_ECB"); */
500
501    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in,
502            inlen, "KEY_AES_256/MODE_CBC");
503    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in,
504            inlen, "KEY_AES_256/MODE_ECB");
505
506    /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that
507     * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be
508     * investigated.
509     */
510    /*
511     crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 0, in, inlen, "KEY_AES_192/MODE_CBC");
512     crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 0, in, inlen, "KEY_AES_192/MODE_ECB");
513     crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 0, in, inlen, "KEY_AES_128/MODE_CBC");
514     crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 0, in, inlen, "KEY_AES_128/MODE_ECB");
515     */
516    apr_pool_destroy(pool);
517
518}
519
520/**
521 * Simple test of OpenSSL block crypt.
522 */
523static void test_crypto_block_openssl_pad(abts_case *tc, void *data)
524{
525    apr_pool_t *pool = NULL;
526    const apr_crypto_driver_t *drivers[] = { NULL, NULL };
527
528    const unsigned char *in = (const unsigned char *) TEST_STRING;
529    apr_size_t inlen = sizeof(TEST_STRING);
530
531    apr_pool_create(&pool, NULL);
532    drivers[0] = get_openssl_driver(tc, pool);
533    drivers[1] = get_openssl_driver(tc, pool);
534
535    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1,
536            in, inlen, "KEY_3DES_192/MODE_CBC");
537    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 1,
538            in, inlen, "KEY_3DES_192/MODE_ECB");
539    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in,
540            inlen, "KEY_AES_256/MODE_CBC");
541    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 1, in,
542            inlen, "KEY_AES_256/MODE_ECB");
543    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in,
544            inlen, "KEY_AES_192/MODE_CBC");
545    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in,
546            inlen, "KEY_AES_192/MODE_ECB");
547    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in,
548            inlen, "KEY_AES_128/MODE_CBC");
549    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in,
550            inlen, "KEY_AES_128/MODE_ECB");
551
552    apr_pool_destroy(pool);
553
554}
555
556/**
557 * Simple test of NSS block crypt.
558 */
559static void test_crypto_block_nss_pad(abts_case *tc, void *data)
560{
561    apr_pool_t *pool = NULL;
562    const apr_crypto_driver_t *drivers[] =
563    { NULL, NULL };
564
565    const unsigned char *in = (const unsigned char *) TEST_STRING;
566    apr_size_t inlen = sizeof(TEST_STRING);
567
568    apr_pool_create(&pool, NULL);
569    drivers[0] = get_nss_driver(tc, pool);
570    drivers[1] = get_nss_driver(tc, pool);
571
572    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1,
573            in, inlen, "KEY_3DES_192/MODE_CBC");
574    /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */
575    /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, "KEY_3DES_192/MODE_ECB"); */
576
577    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in,
578            inlen, "KEY_AES_256/MODE_CBC");
579
580    /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */
581    /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, "KEY_AES_256/MODE_ECB");*/
582
583    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in,
584            inlen, "KEY_AES_192/MODE_CBC");
585
586    /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */
587    /*crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen, "KEY_AES_192/MODE_ECB");*/
588
589    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in,
590            inlen, "KEY_AES_128/MODE_CBC");
591
592    /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */
593    /*crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen, "KEY_AES_128/MODE_ECB");*/
594
595    apr_pool_destroy(pool);
596
597}
598
599/**
600 * Encrypt NSS, decrypt OpenSSL.
601 */
602static void test_crypto_block_nss_openssl_pad(abts_case *tc, void *data)
603{
604    apr_pool_t *pool = NULL;
605    const apr_crypto_driver_t *drivers[] = { NULL, NULL };
606
607    const unsigned char *in = (const unsigned char *) TEST_STRING;
608    apr_size_t inlen = sizeof(TEST_STRING);
609
610    apr_pool_create(&pool, NULL);
611    drivers[0] = get_nss_driver(tc, pool);
612    drivers[1] = get_openssl_driver(tc, pool);
613
614    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1,
615            in, inlen, "KEY_3DES_192/MODE_CBC");
616
617    /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */
618    /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, "KEY_3DES_192/MODE_ECB"); */
619
620    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in,
621            inlen, "KEY_AES_256/MODE_CBC");
622
623    /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */
624    /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, "KEY_AES_256/MODE_ECB");*/
625
626    /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that
627     * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be
628     * investigated.
629     */
630    /*
631     crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 1, in, inlen, "KEY_AES_192/MODE_CBC");
632     crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen, "KEY_AES_192/MODE_ECB");
633     crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 1, in, inlen, "KEY_AES_128/MODE_CBC");
634     crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen, "KEY_AES_128/MODE_ECB");
635     */
636    apr_pool_destroy(pool);
637
638}
639
640/**
641 * Encrypt OpenSSL, decrypt NSS.
642 */
643static void test_crypto_block_openssl_nss_pad(abts_case *tc, void *data)
644{
645    apr_pool_t *pool = NULL;
646    const apr_crypto_driver_t *drivers[] = { NULL, NULL };
647
648    const unsigned char *in = (const unsigned char *) TEST_STRING;
649    apr_size_t inlen = sizeof(TEST_STRING);
650
651    apr_pool_create(&pool, NULL);
652    drivers[0] = get_openssl_driver(tc, pool);
653    drivers[1] = get_nss_driver(tc, pool);
654    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1,
655            in, inlen, "KEY_3DES_192/MODE_CBC");
656
657    /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */
658    /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, "KEY_3DES_192/MODE_ECB"); */
659
660    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in,
661            inlen, "KEY_AES_256/MODE_CBC");
662
663    /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */
664    /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, "KEY_AES_256/MODE_ECB");*/
665
666    /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that
667     * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be
668     * investigated.
669     */
670    /*
671     crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 1, in, inlen, "KEY_AES_192/MODE_CBC");
672     crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen, "KEY_AES_192/MODE_ECB");
673     crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 1, in, inlen, "KEY_AES_128/MODE_CBC");
674     crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen, "KEY_AES_128/MODE_ECB");
675     */
676    apr_pool_destroy(pool);
677
678}
679
680/**
681 * Get Types, OpenSSL.
682 */
683static void test_crypto_get_block_key_types_openssl(abts_case *tc, void *data)
684{
685    apr_pool_t *pool = NULL;
686    const apr_crypto_driver_t *driver;
687    apr_crypto_t *f;
688    apr_hash_t *types;
689    int *key_3des_192;
690    int *key_aes_128;
691    int *key_aes_192;
692    int *key_aes_256;
693
694    apr_pool_create(&pool, NULL);
695    driver = get_openssl_driver(tc, pool);
696    if (driver) {
697
698        f = make(tc, pool, driver);
699        apr_crypto_get_block_key_types(&types, f);
700
701        key_3des_192 = apr_hash_get(types, "3des192", APR_HASH_KEY_STRING);
702        ABTS_PTR_NOTNULL(tc, key_3des_192);
703        ABTS_INT_EQUAL(tc, *key_3des_192, APR_KEY_3DES_192);
704
705        key_aes_128 = apr_hash_get(types, "aes128", APR_HASH_KEY_STRING);
706        ABTS_PTR_NOTNULL(tc, key_aes_128);
707        ABTS_INT_EQUAL(tc, *key_aes_128, APR_KEY_AES_128);
708
709        key_aes_192 = apr_hash_get(types, "aes192", APR_HASH_KEY_STRING);
710        ABTS_PTR_NOTNULL(tc, key_aes_192);
711        ABTS_INT_EQUAL(tc, *key_aes_192, APR_KEY_AES_192);
712
713        key_aes_256 = apr_hash_get(types, "aes256", APR_HASH_KEY_STRING);
714        ABTS_PTR_NOTNULL(tc, key_aes_256);
715        ABTS_INT_EQUAL(tc, *key_aes_256, APR_KEY_AES_256);
716
717    }
718
719    apr_pool_destroy(pool);
720
721}
722
723/**
724 * Get Types, NSS.
725 */
726static void test_crypto_get_block_key_types_nss(abts_case *tc, void *data)
727{
728    apr_pool_t *pool = NULL;
729    const apr_crypto_driver_t *driver;
730    apr_crypto_t *f;
731    apr_hash_t *types;
732    int *key_3des_192;
733    int *key_aes_128;
734    int *key_aes_192;
735    int *key_aes_256;
736
737    apr_pool_create(&pool, NULL);
738    driver = get_nss_driver(tc, pool);
739    if (driver) {
740
741        f = make(tc, pool, driver);
742        apr_crypto_get_block_key_types(&types, f);
743
744        key_3des_192 = apr_hash_get(types, "3des192", APR_HASH_KEY_STRING);
745        ABTS_PTR_NOTNULL(tc, key_3des_192);
746        ABTS_INT_EQUAL(tc, *key_3des_192, APR_KEY_3DES_192);
747
748        key_aes_128 = apr_hash_get(types, "aes128", APR_HASH_KEY_STRING);
749        ABTS_PTR_NOTNULL(tc, key_aes_128);
750        ABTS_INT_EQUAL(tc, *key_aes_128, APR_KEY_AES_128);
751
752        key_aes_192 = apr_hash_get(types, "aes192", APR_HASH_KEY_STRING);
753        ABTS_PTR_NOTNULL(tc, key_aes_192);
754        ABTS_INT_EQUAL(tc, *key_aes_192, APR_KEY_AES_192);
755
756        key_aes_256 = apr_hash_get(types, "aes256", APR_HASH_KEY_STRING);
757        ABTS_PTR_NOTNULL(tc, key_aes_256);
758        ABTS_INT_EQUAL(tc, *key_aes_256, APR_KEY_AES_256);
759
760    }
761
762    apr_pool_destroy(pool);
763
764}
765
766/**
767 * Get Modes, OpenSSL.
768 */
769static void test_crypto_get_block_key_modes_openssl(abts_case *tc, void *data)
770{
771    apr_pool_t *pool = NULL;
772    const apr_crypto_driver_t *driver;
773    apr_crypto_t *f;
774    apr_hash_t *modes;
775    int *mode_ecb;
776    int *mode_cbc;
777
778    apr_pool_create(&pool, NULL);
779    driver = get_openssl_driver(tc, pool);
780    if (driver) {
781
782        f = make(tc, pool, driver);
783        apr_crypto_get_block_key_modes(&modes, f);
784
785        mode_ecb = apr_hash_get(modes, "ecb", APR_HASH_KEY_STRING);
786        ABTS_PTR_NOTNULL(tc, mode_ecb);
787        ABTS_INT_EQUAL(tc, *mode_ecb, APR_MODE_ECB);
788
789        mode_cbc = apr_hash_get(modes, "cbc", APR_HASH_KEY_STRING);
790        ABTS_PTR_NOTNULL(tc, mode_cbc);
791        ABTS_INT_EQUAL(tc, *mode_cbc, APR_MODE_CBC);
792
793    }
794
795    apr_pool_destroy(pool);
796
797}
798
799/**
800 * Get Modes, NSS.
801 */
802static void test_crypto_get_block_key_modes_nss(abts_case *tc, void *data)
803{
804    apr_pool_t *pool = NULL;
805    const apr_crypto_driver_t *driver;
806    apr_crypto_t *f;
807    apr_hash_t *modes;
808    int *mode_ecb;
809    int *mode_cbc;
810
811    apr_pool_create(&pool, NULL);
812    driver = get_nss_driver(tc, pool);
813    if (driver) {
814
815        f = make(tc, pool, driver);
816        apr_crypto_get_block_key_modes(&modes, f);
817
818        mode_ecb = apr_hash_get(modes, "ecb", APR_HASH_KEY_STRING);
819        ABTS_PTR_NOTNULL(tc, mode_ecb);
820        ABTS_INT_EQUAL(tc, *mode_ecb, APR_MODE_ECB);
821
822        mode_cbc = apr_hash_get(modes, "cbc", APR_HASH_KEY_STRING);
823        ABTS_PTR_NOTNULL(tc, mode_cbc);
824        ABTS_INT_EQUAL(tc, *mode_cbc, APR_MODE_CBC);
825
826    }
827
828    apr_pool_destroy(pool);
829
830}
831
832abts_suite *testcrypto(abts_suite *suite)
833{
834    suite = ADD_SUITE(suite);
835
836    /* test simple init and shutdown */
837    abts_run_test(suite, test_crypto_init, NULL);
838
839    /* test a simple encrypt / decrypt operation - openssl */
840    abts_run_test(suite, test_crypto_block_openssl, NULL);
841
842    /* test a padded encrypt / decrypt operation - openssl */
843    abts_run_test(suite, test_crypto_block_openssl_pad, NULL);
844
845    /* test a simple encrypt / decrypt operation - nss */
846    abts_run_test(suite, test_crypto_block_nss, NULL);
847
848    /* test a padded encrypt / decrypt operation - nss */
849    abts_run_test(suite, test_crypto_block_nss_pad, NULL);
850
851    /* test encrypt nss / decrypt openssl */
852    abts_run_test(suite, test_crypto_block_nss_openssl, NULL);
853
854    /* test padded encrypt nss / decrypt openssl */
855    abts_run_test(suite, test_crypto_block_nss_openssl_pad, NULL);
856
857    /* test encrypt openssl / decrypt nss */
858    abts_run_test(suite, test_crypto_block_openssl_nss, NULL);
859
860    /* test padded encrypt openssl / decrypt nss */
861    abts_run_test(suite, test_crypto_block_openssl_nss_pad, NULL);
862
863    /* test block key types openssl */
864    abts_run_test(suite, test_crypto_get_block_key_types_openssl, NULL);
865
866    /* test block key types nss */
867    abts_run_test(suite, test_crypto_get_block_key_types_nss, NULL);
868
869    /* test block key modes openssl */
870    abts_run_test(suite, test_crypto_get_block_key_modes_openssl, NULL);
871
872    /* test block key modes nss */
873    abts_run_test(suite, test_crypto_get_block_key_modes_nss, NULL);
874
875    return suite;
876}
877
878#else
879
880/**
881 * Dummy test suite when crypto is turned off.
882 */
883abts_suite *testcrypto(abts_suite *suite)
884{
885    return ADD_SUITE(suite);
886}
887
888#endif /* APU_HAVE_CRYPTO */
889