summaryrefslogtreecommitdiff
path: root/include
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 /include
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
Diffstat (limited to 'include')
-rw-r--r--include/apr_buckets.h18
-rw-r--r--include/apr_ssl.h157
-rw-r--r--include/private/apr_ssl_openssl_private.h41
3 files changed, 214 insertions, 2 deletions
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 */