Apache HTTPD
apr_crypto.c
Go to the documentation of this file.
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 <ctype.h>
18#include <stdio.h>
19
20#include "apu_config.h"
21#include "apu.h"
22#include "apr_pools.h"
23#include "apr_dso.h"
24#include "apr_strings.h"
25#include "apr_hash.h"
26#include "apr_thread_mutex.h"
27#include "apr_lib.h"
28
29#if APU_HAVE_CRYPTO
30
31#include "apu_internal.h"
32#include "apr_crypto_internal.h"
33#include "apr_crypto.h"
34#include "apu_version.h"
35
36static apr_hash_t *drivers = NULL;
37
38#define ERROR_SIZE 1024
39
40#define CLEANUP_CAST (apr_status_t (*)(void*))
41
42#define APR_TYPEDEF_STRUCT(type, incompletion) \
43struct type { \
44 incompletion \
45 void *unk[]; \
46};
47
50 apr_crypto_driver_t *provider;
51)
52
55 apr_crypto_driver_t *provider;
56 const apr_crypto_t *f;
57)
58
61 apr_crypto_driver_t *provider;
62 const apr_crypto_t *f;
63)
64
65typedef struct apr_crypto_clear_t {
66 void *buffer;
69
70#if !APU_DSO_BUILD
71#define DRIVER_LOAD(name,driver_name,pool,params,rv,result) \
72 { \
73 extern const apr_crypto_driver_t driver_name; \
74 apr_hash_set(drivers,name,APR_HASH_KEY_STRING,&driver_name); \
75 if (driver_name.init) { \
76 rv = driver_name.init(pool, params, result); \
77 } \
78 *driver = &driver_name; \
79 }
80#endif
81
82static apr_status_t apr_crypto_term(void *ptr)
83{
84 /* set drivers to NULL so init can work again */
85 drivers = NULL;
86
87 /* Everything else we need is handled by cleanups registered
88 * when we created mutexes and loaded DSOs
89 */
90 return APR_SUCCESS;
91}
92
94{
97
98 if (drivers != NULL) {
99 return APR_SUCCESS;
100 }
101
102 /* Top level pool scope, need process-scope lifetime */
104 parent && parent != pool;
106 pool = parent;
107#if APU_DSO_BUILD
108 /* deprecate in 2.0 - permit implicit initialization */
110#endif
112
115
116 return ret;
117}
118
119static apr_status_t crypto_clear(void *ptr)
120{
122
123 apr_crypto_memzero(clear->buffer, clear->size);
124 clear->buffer = NULL;
125 clear->size = 0;
126
127 return APR_SUCCESS;
128}
129
131 void *buffer, apr_size_t size)
132{
134
135 clear->buffer = buffer;
136 clear->size = size;
137
140
141 return APR_SUCCESS;
142}
143
144#if defined(HAVE_WEAK_SYMBOLS)
146
149{
150 memset(buffer, 0, size);
151}
152#endif
153
155{
156#if defined(WIN32)
158#elif defined(HAVE_MEMSET_S)
159 if (size) {
160 return memset_s(buffer, (rsize_t)size, 0, (rsize_t)size);
161 }
162#elif defined(HAVE_EXPLICIT_BZERO)
164#elif defined(HAVE_WEAK_SYMBOLS)
166#else
168 volatile unsigned char *volatile ptr = buffer;
169 for (i = 0; i < size; ++i) {
170 ptr[i] = 0;
171 }
172#endif
173 return APR_SUCCESS;
174}
175
176APU_DECLARE(int) apr_crypto_equals(const void *buf1, const void *buf2,
178{
179 const unsigned char *p1 = buf1;
180 const unsigned char *p2 = buf2;
181 unsigned char diff = 0;
183
184 for (i = 0; i < size; ++i) {
185 diff |= p1[i] ^ p2[i];
186 }
187
188 return 1 & ((diff - 1) >> 8);
189}
190
192 const apr_crypto_driver_t **driver, const char *name,
193 const char *params, const apu_err_t **result, apr_pool_t *pool)
194{
195#if APU_DSO_BUILD
196 char modname[32];
197 char symname[34];
200#endif
201 apr_status_t rv;
202
203 if (result) {
204 *result = NULL; /* until further notice */
205 }
206
207#if APU_DSO_BUILD
208 rv = apu_dso_mutex_lock();
209 if (rv) {
210 return rv;
211 }
212#endif
214 if (*driver) {
215#if APU_DSO_BUILD
217#endif
218 return APR_SUCCESS;
219 }
220
221 /* The driver must have exactly the same lifetime as the
222 * drivers hash table; ignore the passed-in pool */
224
225#if APU_DSO_BUILD
226#if defined(NETWARE)
227 apr_snprintf(modname, sizeof(modname), "crypto%s.nlm", name);
228#elif defined(WIN32) || defined(__CYGWIN__)
230 "apr_crypto_%s-" APU_STRINGIFY(APU_MAJOR_VERSION) ".dll", name);
231#else
233 "apr_crypto_%s-" APU_STRINGIFY(APU_MAJOR_VERSION) ".so", name);
234#endif
235 apr_snprintf(symname, sizeof(symname), "apr_crypto_%s_driver", name);
236 rv = apu_dso_load(&dso, &symbol, modname, symname, pool);
237 if (rv == APR_SUCCESS || rv == APR_EINIT) { /* previously loaded?!? */
238 apr_crypto_driver_t *d = symbol;
239 rv = APR_SUCCESS;
240 if (d->init) {
241 rv = d->init(pool, params, result);
242 }
243 if (APR_SUCCESS == rv) {
244 *driver = symbol;
247 }
248 }
250
251 if (APR_SUCCESS != rv && result && !*result) {
254 if (err && buffer) {
256 err->msg = buffer;
257 err->reason = apr_pstrdup(pool, modname);
258 *result = err;
259 }
260 }
261
262#else /* not builtin and !APR_HAS_DSO => not implemented */
263 rv = APR_ENOTIMPL;
264
265 /* Load statically-linked drivers: */
266#if APU_HAVE_OPENSSL
267 if (name[0] == 'o' && !strcmp(name, "openssl")) {
269 }
270#endif
271#if APU_HAVE_NSS
272 if (name[0] == 'n' && !strcmp(name, "nss")) {
274 }
275#endif
276#if APU_HAVE_COMMONCRYPTO
277 if (name[0] == 'c' && !strcmp(name, "commoncrypto")) {
279 }
280#endif
281#if APU_HAVE_MSCAPI
282 if (name[0] == 'm' && !strcmp(name, "mscapi")) {
284 }
285#endif
286#if APU_HAVE_MSCNG
287 if (name[0] == 'm' && !strcmp(name, "mscng")) {
289 }
290#endif
291
292#endif
293
294 return rv;
295}
296
305{
306 return driver->name;
307}
308
317 const apr_crypto_t *f)
318{
319 return f->provider->error(result, f);
320}
321
338 const apr_crypto_driver_t *driver, const char *params, apr_pool_t *pool)
339{
340 return driver->make(f, driver, params, pool);
341}
342
353 const apr_crypto_t *f)
354{
355 return f->provider->get_block_key_types(types, f);
356}
357
368 const apr_crypto_t *f)
369{
370 return f->provider->get_block_key_modes(modes, f);
371}
372
391{
392 return f->provider->key(key, rec, f, p);
393}
394
424 apr_size_t *ivSize, const char *pass, apr_size_t passLen,
425 const unsigned char * salt, apr_size_t saltLen,
427 const apr_crypto_block_key_mode_e mode, const int doPad,
428 const int iterations, const apr_crypto_t *f, apr_pool_t *p)
429{
430 return f->provider->passphrase(key, ivSize, pass, passLen, salt, saltLen,
431 type, mode, doPad, iterations, f, p);
432}
433
451 apr_crypto_block_t **ctx, const unsigned char **iv,
453{
454 return key->provider->block_encrypt_init(ctx, iv, key, blockSize, p);
455}
456
476 apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
478{
479 return ctx->provider->block_encrypt(out, outlen, in, inlen, ctx);
480}
481
502{
503 return ctx->provider->block_encrypt_finish(out, outlen, ctx);
504}
505
521 const unsigned char *iv, const apr_crypto_key_t *key, apr_pool_t *p)
522{
523 return key->provider->block_decrypt_init(ctx, blockSize, iv, key, p);
524}
525
545 apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
547{
548 return ctx->provider->block_decrypt(out, outlen, in, inlen, ctx);
549}
550
571{
572 return ctx->provider->block_decrypt_finish(out, outlen, ctx);
573}
574
582{
583 return ctx->provider->block_cleanup(ctx);
584}
585
593{
594 return f->provider->cleanup(f);
595}
596
604{
605 return driver->shutdown();
606}
607
608#endif /* APU_HAVE_CRYPTO */
APR-UTIL Crypto library.
static apr_hash_t * drivers
Definition apr_dbd.c:36
#define DRIVER_LOAD(name, driver, pool)
Definition apr_dbd.c:69
APR Dynamic Object Handling Routines.
APR Hash Tables.
APR general purpose library routines.
APR memory allocation.
APU_DECLARE(void)
Computes SipHash-2-4, producing a 64bit (APR_SIPHASH_DSIZE) hash from a message and a 128bit (APR_SIP...
Definition apr_sha1.c:206
apr_size_t const unsigned char unsigned int unsigned int d
Definition apr_siphash.h:72
APR Strings library.
APR Thread Mutex Routines.
APR-util Versioning Interface.
#define APU_STRINGIFY(n)
Definition apu_version.h:87
#define APU_MAJOR_VERSION
Definition apu_version.h:53
#define APR_ENOTIMPL
Definition apr_errno.h:476
#define APR_EINIT
Definition apr_errno.h:474
const char * salt
Definition apr_md5.h:139
apr_file_t * f
apr_brigade_flush void * ctx
const char const apr_dbd_driver_t ** driver
Definition apr_dbd.h:106
apr_dbd_transaction_t int mode
Definition apr_dbd.h:261
apr_pool_t const char * params
Definition apr_dbd.h:141
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
const char * key
int type
char * buffer
apr_array_header_t ** result
#define APR_HASH_KEY_STRING
Definition apr_hash.h:47
void * rec
Definition apr_hash.h:270
apr_pool_t * parent
Definition apr_pools.h:197
const char apr_status_t(*) apr_pool_t *poo __attribute__)((nonnull(2, 4)))
Definition apr_pools.h:567
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
apr_int32_t apr_int32_t apr_int32_t err
apr_int32_t in
apr_pool_t * p
Definition md_event.c:32
static apr_file_t * out
Definition mod_info.c:85
static const char *const types[]
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
char * name