summaryrefslogtreecommitdiff
path: root/crypto/apr_crypto_internal.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/apr_crypto_internal.c')
-rw-r--r--crypto/apr_crypto_internal.c238
1 files changed, 238 insertions, 0 deletions
diff --git a/crypto/apr_crypto_internal.c b/crypto/apr_crypto_internal.c
new file mode 100644
index 000000000..66e340c05
--- /dev/null
+++ b/crypto/apr_crypto_internal.c
@@ -0,0 +1,238 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apu.h"
+#include "apr_crypto.h"
+#include "apr_crypto_internal.h"
+
+#if APU_HAVE_CRYPTO
+
+#if APU_HAVE_OPENSSL
+
+#include <openssl/crypto.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+
+apr_status_t apr__crypto_openssl_init(const char *params,
+ const apu_err_t **result,
+ apr_pool_t *pool)
+{
+#if APR_USE_OPENSSL_PRE_1_1_API
+ (void)CRYPTO_malloc_init();
+#else
+ OPENSSL_malloc_init();
+#endif
+ ERR_load_crypto_strings();
+ /* SSL_load_error_strings(); */
+ OpenSSL_add_all_algorithms();
+ ENGINE_load_builtin_engines();
+ ENGINE_register_all_complete();
+
+ return APR_SUCCESS;
+}
+
+apr_status_t apr__crypto_openssl_term(void)
+{
+ ERR_free_strings();
+ EVP_cleanup();
+ ENGINE_cleanup();
+
+ return APR_SUCCESS;
+}
+
+#endif /* APU_HAVE_OPENSSL */
+
+
+#if APU_HAVE_NSS
+
+#include <prerror.h>
+
+#ifdef HAVE_NSS_NSS_H
+#include <nss/nss.h>
+#endif
+#ifdef HAVE_NSS_H
+#include <nss.h>
+#endif
+
+apr_status_t apr__crypto_nss_init(const char *params,
+ const apu_err_t **result,
+ apr_pool_t *pool)
+{
+ SECStatus s;
+ const char *dir = NULL;
+ const char *keyPrefix = NULL;
+ const char *certPrefix = NULL;
+ const char *secmod = NULL;
+ int noinit = 0;
+ PRUint32 flags = 0;
+
+ struct {
+ const char *field;
+ const char *value;
+ int set;
+ } fields[] = {
+ { "dir", NULL, 0 },
+ { "key3", NULL, 0 },
+ { "cert7", NULL, 0 },
+ { "secmod", NULL, 0 },
+ { "noinit", NULL, 0 },
+ { NULL, NULL, 0 }
+ };
+ const char *ptr;
+ size_t klen;
+ char **elts = NULL;
+ char *elt;
+ int i = 0, j;
+ apr_status_t status;
+
+ if (params) {
+ if (APR_SUCCESS != (status = apr_tokenize_to_argv(params, &elts, pool))) {
+ return status;
+ }
+ while ((elt = elts[i])) {
+ ptr = strchr(elt, '=');
+ if (ptr) {
+ for (klen = ptr - elt; klen && apr_isspace(elt[klen - 1]); --klen)
+ ;
+ ptr++;
+ }
+ else {
+ for (klen = strlen(elt); klen && apr_isspace(elt[klen - 1]); --klen)
+ ;
+ }
+ elt[klen] = 0;
+
+ for (j = 0; fields[j].field != NULL; ++j) {
+ if (klen && !strcasecmp(fields[j].field, elt)) {
+ fields[j].set = 1;
+ if (ptr) {
+ fields[j].value = ptr;
+ }
+ break;
+ }
+ }
+
+ i++;
+ }
+ dir = fields[0].value;
+ keyPrefix = fields[1].value;
+ certPrefix = fields[2].value;
+ secmod = fields[3].value;
+ noinit = fields[4].set;
+ }
+
+ /* if we've been asked to bypass, do so here */
+ if (noinit) {
+ return APR_SUCCESS;
+ }
+
+ /* sanity check - we can only initialise NSS once */
+ if (NSS_IsInitialized()) {
+ return APR_EREINIT;
+ }
+
+ if (keyPrefix || certPrefix || secmod) {
+ s = NSS_Initialize(dir, certPrefix, keyPrefix, secmod, flags);
+ }
+ else if (dir) {
+ s = NSS_InitReadWrite(dir);
+ }
+ else {
+ s = NSS_NoDB_Init(NULL);
+ }
+ if (s != SECSuccess) {
+ if (result) {
+ /* Note: all memory must be owned by the caller, in case we're unloaded */
+ apu_err_t *err = apr_pcalloc(pool, sizeof(apu_err_t));
+ err->rc = PR_GetError();
+ err->msg = apr_pstrdup(pool, PR_ErrorToName(s));
+ err->reason = apr_pstrdup(pool, "Error during 'nss' initialisation");
+ *result = err;
+ }
+
+ return APR_ECRYPT;
+ }
+
+ return APR_SUCCESS;
+}
+
+apr_status_t apr__crypto_nss_term(void)
+{
+ if (NSS_IsInitialized()) {
+ SECStatus s = NSS_Shutdown();
+ if (s != SECSuccess) {
+ fprintf(stderr, "NSS failed to shutdown, possible leak: %d: %s",
+ PR_GetError(), PR_ErrorToName(s));
+ return APR_EINIT;
+ }
+ }
+ return APR_SUCCESS;
+}
+
+#endif /* APU_HAVE_NSS */
+
+
+#if APU_HAVE_COMMONCRYPTO
+
+apr_status_t apr__crypto_commoncrypto_init(const char *params,
+ const apu_err_t **result,
+ apr_pool_t *pool)
+{
+ return APR_SUCCESS;
+}
+
+apr_status_t apr__crypto_commoncrypto_term(void)
+{
+ return APR_SUCCESS;
+}
+
+#endif /* APU_HAVE_COMMONCRYPTO */
+
+
+#if APU_HAVE_MSCAPI
+
+apr_status_t apr__crypto_commoncrypto_init(const char *params,
+ const apu_err_t **result,
+ apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+
+apr_status_t apr__crypto_commoncrypto_term(void)
+{
+ return APR_ENOTIMPL;
+}
+
+#endif /* APU_HAVE_MSCAPI */
+
+
+#if APU_HAVE_MSCNG
+
+apr_status_t apr__crypto_commoncrypto_init(const char *params,
+ const apu_err_t **result,
+ apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+
+apr_status_t apr__crypto_commoncrypto_term(void)
+{
+ return APR_ENOTIMPL;
+}
+
+#endif /* APU_HAVE_MSCNG */
+
+#endif /* APU_HAVE_CRYPTO */