summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorminfrin <minfrin@13f79535-47bb-0310-9956-ffa450edef68>2007-11-21 21:01:50 +0000
committerminfrin <minfrin@13f79535-47bb-0310-9956-ffa450edef68>2007-11-21 21:01:50 +0000
commit5139ddb3433c90e1f7a653dafc921356b8712c25 (patch)
tree3ceec32543d53a040ef01794f5a93a13f98b1f6c
parent7b9eadc1fe7ed8c256c2ecbd5b47cab0444ac12b (diff)
downloadlibapr-util-5139ddb3433c90e1f7a653dafc921356b8712c25.tar.gz
Expose the SSL EVP interface to encrypt and decrypt arbitrary
blocks of data, using symmetrical keys. Experimental support for asymmetrical public/private keys as supported by OpenSSL v0.9.9. git-svn-id: http://svn.apache.org/repos/asf/apr/apr-util/trunk@597209 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES7
-rw-r--r--build/ssl.m44
-rw-r--r--include/apr_buckets.h18
-rw-r--r--include/apr_ssl.h157
-rw-r--r--include/private/apr_ssl_openssl_private.h41
-rw-r--r--ssl/apr_ssl_openssl.c294
-rw-r--r--ssl/apr_ssl_winsock.c49
7 files changed, 566 insertions, 4 deletions
diff --git a/CHANGES b/CHANGES
index af6447a8..b1f29a1c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,11 @@
-*- coding: utf-8 -*-
Changes with APR-util 1.3.0
-
+
+ *) Expose the SSL EVP interface to encrypt and decrypt arbitrary
+ blocks of data, using symmetrical keys. Experimental support for
+ asymmetrical public/private keys as supported by OpenSSL v0.9.9.
+ [Graham Leggett]
+
*) Introduce apr_dbd_open_ex() [Bojan Smojver]
*) Make md5 hash files portable between EBCDIC and ASCII platforms
diff --git a/build/ssl.m4 b/build/ssl.m4
index 13d9bc9b..d51602e3 100644
--- a/build/ssl.m4
+++ b/build/ssl.m4
@@ -86,6 +86,9 @@ AC_DEFUN([APU_CHECK_OPENSSL], [
fi
fi
+ AC_CHECK_DECLS([EVP_PKEY_CTX_new], [], [],
+ [#include <openssl/evp.h>])
+
CPPFLAGS="$old_cppflags"
LDFLAGS="$old_ldflags"
fi
@@ -97,7 +100,6 @@ AC_DEFUN([APU_CHECK_OPENSSL], [
fi
])
-
AC_SUBST(apu_have_openssl)
dnl Add the libraries we will need now that we have set apu_have_openssl correctly
diff --git a/include/apr_buckets.h b/include/apr_buckets.h
index 829c635c..2fe85195 100644
--- a/include/apr_buckets.h
+++ b/include/apr_buckets.h
@@ -971,7 +971,16 @@ APU_DECLARE_NONSTD(void) apr_bucket_free(void *block);
} while (0)
/**
- * read the data from the bucket
+ * Read the data from the bucket.
+ *
+ * If it is not practical to return all
+ * the data in the bucket, the current bucket is split and replaced by
+ * two buckets, the first representing the data returned in this call,
+ * and the second representing the rest of the data as yet unread. The
+ * original bucket will become the first bucket after this call.
+ *
+ * (It is assumed that the bucket is a member of a brigade when this
+ * function is called).
* @param e The bucket to read from
* @param str The location to store the data in
* @param len The amount of data read
@@ -988,7 +997,12 @@ APU_DECLARE_NONSTD(void) apr_bucket_free(void *block);
#define apr_bucket_setaside(e,p) (e)->type->setaside(e,p)
/**
- * Split one bucket in two.
+ * Split one bucket in two at the point provided.
+ *
+ * Once split, the original bucket becomes the first of the two new buckets.
+ *
+ * (It is assumed that the bucket is a member of a brigade when this
+ * function is called).
* @param e The bucket to split
* @param point The offset to split the bucket at
*/
diff --git a/include/apr_ssl.h b/include/apr_ssl.h
index 45fe498a..99ab9bde 100644
--- a/include/apr_ssl.h
+++ b/include/apr_ssl.h
@@ -254,6 +254,163 @@ APU_DECLARE(apr_status_t) apr_pollset_remove_ssl_socket(apr_ssl_socket_t *);
APU_DECLARE(apr_status_t) apr_ssl_socket_set_poll_events(apr_ssl_socket_t *,
apr_int16_t);
+
+
+/**
+ * Values that determine how a created factory will be used.
+ */
+typedef enum {
+ APR_EVP_FACTORY_SYM, /**< Factory is for symmetrical operations */
+ APR_EVP_FACTORY_ASYM /**< Factory is for asymmetrical operations */
+} apr_evp_factory_type_e;
+
+/**
+ * Values that determine whether we need to encrypt or decrypt.
+ */
+typedef enum {
+ APR_EVP_DECRYPT=0,
+ APR_EVP_ENCRYPT=1
+} apr_evp_crypt_type_e;
+
+/**
+ * Values that determine which key to use during encrypt or decrypt.
+ */
+typedef enum {
+ APR_EVP_KEY_SYM=0, /* Use a passphrase / symmetrical */
+ APR_EVP_KEY_PUBLIC=1, /* Use the public key / asymmetrical */
+ APR_EVP_KEY_PRIVATE=2 /* Use the private key / asymetrical */
+} apr_evp_crypt_key_e;
+
+/**
+ * Structure for referencing an evp "factory"
+ */
+typedef struct apu_evp_factory apr_evp_factory_t;
+
+/**
+ * Structure for referencing an EVP PKEY context.
+ */
+typedef struct apu_evp_crypt apr_evp_crypt_t;
+
+/**
+ * @fn apr_status_t apr_evp_factory_create(apr_evp_factory_t **newFactory,
+ const char *privateKeyFilename,
+ const char *certificateFilename,
+ const char *cipherName,
+ const char *passphrase,
+ const char *engine,
+ const char *digest,
+ apr_evp_factory_type_e purpose,
+ apr_pool_t *pool)
+ * @brief Attempts to create an EVP "factory". The "factory" is then
+ * used to create contexts to keep track of encryption.
+ * @param newFactory The newly created factory
+ * @param privateKeyFilename Private key filename to use for assetrical encryption
+ * @param certificateFilename X509 certificate file to use for assymetrical encryption
+ * @param cipherName Name of cipher to use for symmetrical encryption
+ * @param passphrase Passphrase to use for assymetrical encryption
+ * @param purpose Constant that determines how the created factory will be used
+ * @param pool The pool to use for memory allocations
+ * @return an APR_ status code. APR_ENOCERT will be returned if the certificates
+ * cannot be loaded, APR_ENOCIPHER if the cipher cannot be found.
+ * APR_ENODIGEST if the digest cannot be found. APR_ENOTIMPL will
+ * be returned if not supported.
+ */
+APU_DECLARE(apr_status_t) apr_evp_factory_create(apr_evp_factory_t **newFactory,
+ const char *privateKeyFn,
+ const char *certFn,
+ const char *cipherName,
+ const char *passphrase,
+ const char *engine,
+ const char *digest,
+ apr_evp_factory_type_e purpose,
+ apr_pool_t *pool);
+
+/**
+ * @fn apr_status_t apr_evp_crypt_init(apr_evp_factory_t *,
+ * apr_evp_crypt_t **e,
+ * apr_evp_crypt_type_e type,
+ * apr_evp_crypt_key_e key,
+ * apr_pool_t *p)
+ * @brief Initialise a context for encrypting arbitrary data.
+ * @note If *e is NULL, a apr_evp_crypt_t will be created from a pool. If
+ * *e is not NULL, *e must point at a previously created structure.
+ * @param factory The EVP factory containing keys to use.
+ * @param evp The evp context returned, see note.
+ * @param type Whether to encrypt or decrypt.
+ * @param key Which key to use.
+ * @param p The pool to use.
+ * @return APR_EINIT if initialisation unsuccessful. Returns
+ * APR_ENOTIMPL if not supported.
+ */
+APR_DECLARE(apr_status_t) apr_evp_crypt_init(apr_evp_factory_t *,
+ apr_evp_crypt_t **e,
+ apr_evp_crypt_type_e type,
+ apr_evp_crypt_key_e key,
+ apr_pool_t *p);
+
+/**
+ * @fn apr_status_t apr_evp_crypt(apr_evp_crypt_t *evp,
+ * unsigned char *out,
+ * apr_size_t *outlen,
+ * const unsigned char *in,
+ * apr_size_t inlen)
+ * @brief Encrypt/decrypt data provided by in, write it to out.
+ * @note The number of bytes written will be written to outlen. If
+ * out is NULL, outlen will contain the maximum size of the
+ * buffer needed to hold the data.
+ * @param evp The evp context to use.
+ * @param out Address of a buffer to which data will be written,
+ * see note.
+ * @param outlen Length of the output will be written here.
+ * @param in Address of the buffer to read.
+ * @param inlen Length of the buffer to read.
+ * @return APR_EGENERAL if an error occurred. Returns APR_ENOTIMPL if
+ * not supported.
+ */
+APR_DECLARE(apr_status_t) apr_evp_crypt(apr_evp_crypt_t *,
+ unsigned char **out,
+ apr_size_t *outlen,
+ const unsigned char *in,
+ apr_size_t inlen);
+
+/**
+ * @fn apr_status_t apr_evp_crypt_finish(apr_evp_crypt_t *,
+ * unsigned char *out,
+ * apr_size_t *outlen)
+ * @brief Encrypt final data block, write it to out.
+ * @note If necessary the final block will be written out after being
+ * padded. After this call, the context is cleaned and can be
+ * reused by apr_env_encrypt_init() or apr_env_decrypt_init().
+ * @param evp The evp context to use.
+ * @param out Address of a buffer to which data will be written.
+ * @param outlen Length of the output will be written here.
+ * @return APR_EGENERAL if an error occurred. Returns APR_ENOTIMPL if
+ * not supported.
+ */
+APR_DECLARE(apr_status_t) apr_evp_crypt_finish(apr_evp_crypt_t *e,
+ unsigned char *out,
+ apr_size_t *outlen);
+
+
+/**
+ * @fn apr_status_t apr_evp_crypt_cleanup(apr_evp_crypt_t *e)
+ * @brief Clean encryption / decryption context.
+ * @note After cleanup, a context is free to be reused if necessary.
+ * @param evp The evp context to use.
+ * @return Returns APR_ENOTIMPL if not supported.
+ */
+APR_DECLARE(apr_status_t) apr_evp_crypt_cleanup(apr_evp_crypt_t *e);
+
+/**
+ * @fn apr_status_t apr_evp_factory_cleanup(apr_evp_factory_t *f)
+ * @brief Clean encryption / decryption factory.
+ * @note After cleanup, a factory is free to be reused if necessary.
+ * @param f The factory to use.
+ * @return Returns APR_ENOTIMPL if not supported.
+ */
+APR_DECLARE(apr_status_t) apr_evp_factory_cleanup(apr_evp_factory_t *f);
+
+
/** @} */
#ifdef __cplusplus
}
diff --git a/include/private/apr_ssl_openssl_private.h b/include/private/apr_ssl_openssl_private.h
index af968d40..3ef3a982 100644
--- a/include/private/apr_ssl_openssl_private.h
+++ b/include/private/apr_ssl_openssl_private.h
@@ -32,6 +32,47 @@ struct apu_ssl_socket_data {
int sslErr; /** SSL_get_error() code */
};
+typedef struct apu_evp_data apu_evp_data_t;
+
+/**
+ * EVP factory structure
+ */
+struct apu_evp_factory {
+ apr_pool_t *pool; /**< pool to use for memory allocations */
+ apr_evp_factory_type_e purpose; /**< Purpose of the factory */
+ apu_evp_data_t *evpData; /**< Pointer to implementation specific data */
+};
+
+/**
+ * Define the cipher context structure used as a handle by
+ * the generic apu_evp_* functions.
+ */
+struct apu_evp_data {
+ const EVP_CIPHER *cipher;
+ const EVP_MD *md;
+ unsigned char salt[8];
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+ const char *privateKeyFilename;
+ const char *certificateFilename;
+#if HAVE_DECL_EVP_PKEY_CTX_NEW
+ SSL_CTX *sslCtx;
+ SSL *ssl;
+ EVP_PKEY *pubkey;
+ EVP_PKEY *privkey;
+#endif
+};
+
+struct apu_evp_crypt {
+ apr_pool_t *pool;
+ EVP_CIPHER_CTX *cipherCtx;
+#if HAVE_DECL_EVP_PKEY_CTX_NEW
+ EVP_PKEY_CTX *pkeyCtx;
+#endif
+ apr_evp_factory_type_e purpose;
+ apr_evp_crypt_type_e type;
+ apr_evp_crypt_key_e key;
+};
#endif /* APU_HAVE_OPENSSL */
diff --git a/ssl/apr_ssl_openssl.c b/ssl/apr_ssl_openssl.c
index 9e1258fb..480a3bd8 100644
--- a/ssl/apr_ssl_openssl.c
+++ b/ssl/apr_ssl_openssl.c
@@ -231,4 +231,298 @@ apr_status_t apu_ssl_raw_error(apr_ssl_socket_t *sock)
return APR_SUCCESS;
}
+apr_status_t apr_evp_crypt_cleanup(apr_evp_crypt_t *e)
+{
+
+#if HAVE_DECL_EVP_PKEY_CTX_NEW
+ if (e->pkeyCtx) {
+ EVP_PKEY_CTX_free(e->pkeyCtx);
+ e->pkeyCtx = NULL;
+ }
+#endif
+ if (e->cipherCtx) {
+ EVP_CIPHER_CTX_cleanup(e->cipherCtx);
+ e->cipherCtx = NULL;
+ }
+
+ return APR_SUCCESS;
+
+}
+
+apr_status_t apr_evp_crypt_cleanup_helper(void *data)
+{
+ apr_evp_crypt_t *f = (apr_evp_crypt_t *)data;
+ return apr_evp_crypt_cleanup(f);
+}
+
+apr_status_t apr_evp_factory_cleanup(apr_evp_factory_t *f)
+{
+ apu_evp_data_t *evpData = f->evpData;
+ int i;
+
+ for (i = 0; i < EVP_MAX_KEY_LENGTH; evpData->key[i++] = 0);
+ for (i = 0; i < EVP_MAX_IV_LENGTH; evpData->iv[i++] = 0);
+#if HAVE_DECL_EVP_PKEY_CTX_NEW
+ if (evpData->ssl) {
+ SSL_free(evpData->ssl);
+ evpData->ssl = NULL;
+ }
+ if (evpData->sslCtx) {
+ SSL_CTX_free(evpData->sslCtx);
+ evpData->sslCtx = NULL;
+ }
#endif
+
+ return APR_SUCCESS;
+
+}
+
+apr_status_t apr_evp_factory_cleanup_helper(void *data)
+{
+ apr_evp_factory_t *f = (apr_evp_factory_t *)data;
+ return apr_evp_factory_cleanup(f);
+}
+
+apr_status_t apr_evp_factory_create(apr_evp_factory_t **newFactory,
+ const char *privateKeyFn,
+ const char *certFn,
+ const char *cipherName,
+ const char *passphrase,
+ const char *engine,
+ const char *digest,
+ apr_evp_factory_type_e purpose,
+ apr_pool_t *pool)
+{
+ apr_evp_factory_t *f = (apr_evp_factory_t *)apr_pcalloc(pool, sizeof(apr_evp_factory_t));
+ if (!f) {
+ return APR_ENOMEM;
+ }
+ *newFactory = f;
+ f->pool = pool;
+ f->purpose = purpose;
+
+ apu_evp_data_t *data = (apu_evp_data_t *)apr_pcalloc(pool, sizeof(apu_evp_data_t));
+ if (!data) {
+ return APR_ENOMEM;
+ }
+ f->evpData = data;
+ apr_pool_cleanup_register(pool, f,
+ apr_evp_factory_cleanup_helper,
+ apr_pool_cleanup_null);
+
+ switch (purpose) {
+ case APR_EVP_FACTORY_ASYM: {
+#if HAVE_DECL_EVP_PKEY_CTX_NEW
+ /* load certs */
+ data->sslCtx = SSL_CTX_new(SSLv23_server_method());
+ if (data->sslCtx) {
+ if (!SSL_CTX_use_PrivateKey_file(data->sslCtx, privateKeyFn,
+ SSL_FILETYPE_PEM) ||
+ !SSL_CTX_use_certificate_file(data->sslCtx, certFn,
+ SSL_FILETYPE_PEM) ||
+ !SSL_CTX_check_private_key(data->sslCtx)) {
+ SSL_CTX_free(data->sslCtx);
+ return APR_ENOCERT;
+ }
+ data->ssl = SSL_new(data->sslCtx);
+ if (data->ssl) {
+ data->privkey = SSL_get_privatekey(data->ssl);
+ X509 *cert = SSL_get_certificate(data->ssl);
+ if (cert) {
+ data->pubkey = X509_get_pubkey(cert);
+ }
+ }
+ }
+#else
+ return APR_ENOTIMPL;
+#endif
+ }
+ case APR_EVP_FACTORY_SYM: {
+ data->cipher = EVP_get_cipherbyname(cipherName);
+ if (!data->cipher) {
+ return APR_ENOCIPHER;
+ }
+ OpenSSL_add_all_digests();
+ data->md = EVP_get_digestbyname(digest);
+ if (!data->md) {
+ return APR_ENODIGEST;
+ }
+ EVP_BytesToKey(data->cipher, data->md,
+ data->salt,
+ (const unsigned char *)passphrase, strlen(passphrase), 1,
+ data->key, data->iv);
+ }
+ }
+
+ return APR_SUCCESS;
+
+}
+
+apr_status_t apr_evp_crypt_init(apr_evp_factory_t *f,
+ apr_evp_crypt_t **e,
+ apr_evp_crypt_type_e type,
+ apr_evp_crypt_key_e key,
+ apr_pool_t *p)
+{
+ apu_evp_data_t *data = f->evpData;
+
+ if (!*e) {
+ *e = (apr_evp_crypt_t *)apr_pcalloc(p, sizeof(apr_evp_crypt_t));
+ }
+ (*e)->pool = p;
+ (*e)->purpose = f->purpose;
+ (*e)->type = type;
+ (*e)->key = key;
+
+ switch (f->purpose) {
+ case APR_EVP_FACTORY_ASYM: {
+#if HAVE_DECL_EVP_PKEY_CTX_NEW
+
+ /* todo: add ENGINE support */
+ if (APR_EVP_KEY_PUBLIC == type) {
+ (*e)->pkeyCtx = EVP_PKEY_CTX_new(data->pubkey, NULL);
+ }
+ else if (APR_EVP_KEY_PRIVATE == type) {
+ (*e)->pkeyCtx = EVP_PKEY_CTX_new(data->privkey, NULL);
+ }
+ apr_pool_cleanup_register(p, *e, apr_evp_crypt_cleanup_helper,
+ apr_pool_cleanup_null);
+
+ if (APR_EVP_ENCRYPT == type) {
+ if (EVP_PKEY_encrypt_init((*e)->pkeyCtx) <= 0) {
+ return APR_EINIT;
+ }
+ }
+ else if (APR_EVP_DECRYPT == type) {
+ if (EVP_PKEY_decrypt_init((*e)->pkeyCtx) <= 0) {
+ return APR_EINIT;
+ }
+ }
+
+ return APR_SUCCESS;
+
+#else
+ return APR_ENOTIMPL;
+#endif
+ }
+ case APR_EVP_FACTORY_SYM: {
+ if (!(*e)->cipherCtx) {
+ (*e)->cipherCtx = (EVP_CIPHER_CTX *)apr_pcalloc(p, sizeof(EVP_CIPHER_CTX));
+ if (!(*e)->cipherCtx) {
+ return APR_ENOMEM;
+ }
+ }
+ EVP_CIPHER_CTX_init((*e)->cipherCtx);
+ EVP_CipherInit_ex((*e)->cipherCtx, data->cipher, NULL, data->key, data->iv, type);
+ return APR_SUCCESS;
+ }
+ }
+
+ return APR_EINIT;
+
+}
+
+apr_status_t apr_evp_crypt(apr_evp_crypt_t *e,
+ unsigned char **out,
+ apr_size_t *outlen,
+ const unsigned char *in,
+ apr_size_t inlen)
+{
+ unsigned char *buffer;
+
+ switch (e->purpose) {
+ case APR_EVP_FACTORY_ASYM: {
+#if HAVE_DECL_EVP_PKEY_CTX_NEW
+ if (!out || !*out) {
+ if (APR_EVP_ENCRYPT == e->type &&
+ EVP_PKEY_encrypt(e->pkeyCtx, NULL, outlen,
+ in, inlen) <= 0) {
+ return APR_EGENERAL;
+ }
+ if (APR_EVP_DECRYPT == e->type &&
+ EVP_PKEY_decrypt(e->pkeyCtx, NULL, outlen,
+ in, inlen) <= 0) {
+ return APR_EGENERAL;
+ }
+ if (!out) {
+ return APR_SUCCESS;
+ }
+ buffer = apr_palloc(e->pool, *outlen + 1);
+ if (!buffer) {
+ return APR_ENOMEM;
+ }
+ *out = buffer;
+ buffer[*outlen] = 0;
+ }
+ if (APR_EVP_ENCRYPT == e->type &&
+ EVP_PKEY_encrypt(e->pkeyCtx, *out, outlen,
+ in, inlen) <= 0) {
+ return APR_EGENERAL;
+ }
+ if (APR_EVP_DECRYPT == e->type &&
+ EVP_PKEY_decrypt(e->pkeyCtx, *out, outlen,
+ in, inlen) <= 0) {
+ return APR_EGENERAL;
+ }
+
+ return APR_SUCCESS;
+
+#else
+ return APR_ENOTIMPL;
+#endif
+ }
+ case APR_EVP_FACTORY_SYM: {
+ int len = (int)*outlen;
+ if (!out) {
+ *outlen = inlen + EVP_MAX_BLOCK_LENGTH;
+ return APR_SUCCESS;
+ }
+ if (!*out) {
+ buffer = apr_palloc(e->pool, inlen + EVP_MAX_BLOCK_LENGTH);
+ if (!buffer) {
+ return APR_ENOMEM;
+ }
+ *out = buffer;
+ }
+ if(!EVP_CipherUpdate(e->cipherCtx, *out, &len, in, inlen)) {
+ return APR_EGENERAL;
+ }
+ *outlen = (apr_size_t)len;
+ return APR_SUCCESS;
+ }
+ }
+
+ return APR_EGENERAL;
+
+}
+
+apr_status_t apr_evp_crypt_finish(apr_evp_crypt_t *e,
+ unsigned char *out,
+ apr_size_t *outlen)
+{
+
+ switch (e->purpose) {
+ case APR_EVP_FACTORY_ASYM: {
+#if HAVE_DECL_EVP_PKEY_CTX_NEW
+ break;
+#else
+ return APR_ENOTIMPL;
+#endif
+ }
+ case APR_EVP_FACTORY_SYM: {
+ int tlen;
+ if(!EVP_CipherFinal_ex(e->cipherCtx, out, &tlen)) {
+ return APR_EGENERAL;
+ }
+ *outlen = tlen;
+ break;
+ }
+ }
+ apr_evp_crypt_cleanup(e);
+
+ return APR_SUCCESS;
+
+}
+
+#endif
+
diff --git a/ssl/apr_ssl_winsock.c b/ssl/apr_ssl_winsock.c
index c43d9140..9a80bfe3 100644
--- a/ssl/apr_ssl_winsock.c
+++ b/ssl/apr_ssl_winsock.c
@@ -245,4 +245,53 @@ apr_status_t apu_ssl_raw_error(apr_ssl_socket_t *sock)
return APR_SUCCESS;
}
+apr_status_t apr_evp_crypt_cleanup(apr_evp_crypt_t *e)
+{
+ return APR_ENOTIMPL;
+}
+
+apr_status_t apr_evp_factory_cleanup(apr_evp_factory_t *f)
+{
+ return APR_ENOTIMPL;
+}
+
+apr_status_t apr_evp_factory_create(apr_evp_factory_t **newFactory,
+ const char *privateKeyFn,
+ const char *certFn,
+ const char *cipherName,
+ const char *passphrase,
+ const char *engine,
+ const char *digest,
+ apr_evp_factory_type_e purpose,
+ apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+
+apr_status_t apr_status_t apr_evp_crypt_init(apr_evp_factory_t *f,
+ apr_evp_crypt_t **e,
+ apr_evp_crypt_type_e type,
+ apr_evp_crypt_key_e key,
+ apr_pool_t *p)
+{
+ return APR_ENOTIMPL;
+}
+
+apr_status_t apr_evp_crypt(apr_evp_crypt_t *,
+ unsigned char **out,
+ apr_size_t *outlen,
+ const unsigned char *in,
+ apr_size_t inlen)
+{
+ return APR_ENOTIMPL;
+}
+
+apr_status_t apr_evp_crypt_finish(apr_evp_crypt_t *e,
+ unsigned char *out,
+ apr_size_t *outlen);
+{
+ return APR_ENOTIMPL;
+}
+
#endif
+