📄 ssl_util.c
字号:
/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed 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. *//* _ _ * _ __ ___ ___ __| | ___ ___| | mod_ssl * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL * | | | | | | (_) | (_| | \__ \__ \ | * |_| |_| |_|\___/ \__,_|___|___/___/_| * |_____| * ssl_util.c * Utility Functions */ /* ``Every day of my life I am forced to add another name to the list of people who piss me off!'' -- Calvin */#include "mod_ssl.h"#include "ap_mpm.h"#include "apr_thread_mutex.h"/* _________________________________________________________________**** Utility Functions** _________________________________________________________________*/char *ssl_util_vhostid(apr_pool_t *p, server_rec *s){ char *id; SSLSrvConfigRec *sc; char *host; apr_port_t port; host = s->server_hostname; if (s->port != 0) port = s->port; else { sc = mySrvConfig(s); if (sc->enabled) port = DEFAULT_HTTPS_PORT; else port = DEFAULT_HTTP_PORT; } id = apr_psprintf(p, "%s:%lu", host, (unsigned long)port); return id;}void ssl_util_strupper(char *s){ for (; *s; ++s) *s = apr_toupper(*s); return;}static const char ssl_util_uuencode_six2pr[64+1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";void ssl_util_uuencode(char *szTo, const char *szFrom, BOOL bPad){ ssl_util_uuencode_binary((unsigned char *)szTo, (const unsigned char *)szFrom, strlen(szFrom), bPad);}void ssl_util_uuencode_binary(unsigned char *szTo, const unsigned char *szFrom, int nLength, BOOL bPad){ const unsigned char *s; int nPad = 0; for (s = szFrom; nLength > 0; s += 3) { *szTo++ = ssl_util_uuencode_six2pr[s[0] >> 2]; *szTo++ = ssl_util_uuencode_six2pr[(s[0] << 4 | s[1] >> 4) & 0x3f]; if (--nLength == 0) { nPad = 2; break; } *szTo++ = ssl_util_uuencode_six2pr[(s[1] << 2 | s[2] >> 6) & 0x3f]; if (--nLength == 0) { nPad = 1; break; } *szTo++ = ssl_util_uuencode_six2pr[s[2] & 0x3f]; --nLength; } while(bPad && nPad--) { *szTo++ = NUL; } *szTo = NUL; return;}apr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd, const char * const *argv){ apr_procattr_t *procattr; apr_proc_t *proc; if (apr_procattr_create(&procattr, p) != APR_SUCCESS) return NULL; if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK, APR_FULL_BLOCK) != APR_SUCCESS) return NULL; if (apr_procattr_dir_set(procattr, ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS) return NULL; if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS) return NULL; if ((proc = (apr_proc_t *)apr_pcalloc(p, sizeof(apr_proc_t))) == NULL) return NULL; if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS) return NULL; return proc->out;}void ssl_util_ppclose(server_rec *s, apr_pool_t *p, apr_file_t *fp){ apr_file_close(fp); return;}/* * Run a filter program and read the first line of its stdout output */char *ssl_util_readfilter(server_rec *s, apr_pool_t *p, const char *cmd, const char * const *argv){ static char buf[MAX_STRING_LEN]; apr_file_t *fp; apr_size_t nbytes = 1; char c; int k; if ((fp = ssl_util_ppopen(s, p, cmd, argv)) == NULL) return NULL; /* XXX: we are reading 1 byte at a time here */ for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS && nbytes == 1 && (k < MAX_STRING_LEN-1) ; ) { if (c == '\n' || c == '\r') break; buf[k++] = c; } buf[k] = NUL; ssl_util_ppclose(s, p, fp); return buf;}BOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p){ apr_finfo_t finfo; if (path == NULL) return FALSE; if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path, APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0) return FALSE; if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG) return FALSE; if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR) return FALSE; if (pcm & SSL_PCM_ISNONZERO && finfo.size <= 0) return FALSE; return TRUE;}ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey) { ssl_algo_t t; t = SSL_ALGO_UNKNOWN; if (pCert != NULL) pKey = X509_get_pubkey(pCert); if (pKey != NULL) { switch (EVP_PKEY_key_type(pKey)) { case EVP_PKEY_RSA: t = SSL_ALGO_RSA; break; case EVP_PKEY_DSA: t = SSL_ALGO_DSA; break; default: break; } } return t;}char *ssl_util_algotypestr(ssl_algo_t t) { char *cp; cp = "UNKNOWN"; switch (t) { case SSL_ALGO_RSA: cp = "RSA"; break; case SSL_ALGO_DSA: cp = "DSA"; break; default: break; } return cp;}char *ssl_util_ptxtsub(apr_pool_t *p, const char *cpLine, const char *cpMatch, char *cpSubst){#define MAX_PTXTSUB 100 char *cppMatch[MAX_PTXTSUB]; char *cpResult; int nResult; int nLine; int nSubst; int nMatch; char *cpI; char *cpO; char *cp; int i; /* * Pass 1: find substitution locations and calculate sizes */ nLine = strlen(cpLine); nMatch = strlen(cpMatch); nSubst = strlen(cpSubst); for (cpI = (char *)cpLine, i = 0, nResult = 0; cpI < cpLine+nLine && i < MAX_PTXTSUB; ) { if ((cp = strstr(cpI, cpMatch)) != NULL) { cppMatch[i++] = cp; nResult += ((cp-cpI)+nSubst); cpI = (cp+nMatch); } else { nResult += strlen(cpI); break; } } cppMatch[i] = NULL; if (i == 0) return NULL; /* * Pass 2: allocate memory and assemble result */ cpResult = apr_pcalloc(p, nResult+1); for (cpI = (char *)cpLine, cpO = cpResult, i = 0; cppMatch[i] != NULL; i++) { apr_cpystrn(cpO, cpI, cppMatch[i]-cpI+1); cpO += (cppMatch[i]-cpI); apr_cpystrn(cpO, cpSubst, nSubst+1); cpO += nSubst; cpI = (cppMatch[i]+nMatch); } apr_cpystrn(cpO, cpI, cpResult+nResult-cpO+1); return cpResult;}/* * certain key and cert data needs to survive restarts, * which are stored in the user data table of s->process->pool. * to prevent "leaking" of this data, we use malloc/free * rather than apr_palloc and these wrappers to help make sure * we do not leak the malloc-ed data. */unsigned char *ssl_asn1_table_set(apr_hash_t *table, const char *key, long int length){ apr_ssize_t klen = strlen(key); ssl_asn1_t *asn1 = apr_hash_get(table, key, klen); /* * if a value for this key already exists, * reuse as much of the already malloc-ed data * as possible. */ if (asn1) { if (asn1->nData != length) { free(asn1->cpData); /* XXX: realloc? */ asn1->cpData = NULL; } } else { asn1 = malloc(sizeof(*asn1)); asn1->source_mtime = 0; /* used as a note for encrypted private keys */ asn1->cpData = NULL; } asn1->nData = length; if (!asn1->cpData) { asn1->cpData = malloc(length); } apr_hash_set(table, key, klen, asn1); return asn1->cpData; /* caller will assign a value to this */}ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table, const char *key){ return (ssl_asn1_t *)apr_hash_get(table, key, APR_HASH_KEY_STRING);}void ssl_asn1_table_unset(apr_hash_t *table, const char *key){ apr_ssize_t klen = strlen(key); ssl_asn1_t *asn1 = apr_hash_get(table, key, klen); if (!asn1) { return; } if (asn1->cpData) { free(asn1->cpData); } free(asn1); apr_hash_set(table, key, klen, NULL);}static const char *ssl_asn1_key_types[] = {"RSA", "DSA"};const char *ssl_asn1_keystr(int keytype){ if (keytype >= SSL_AIDX_MAX) { return NULL; } return ssl_asn1_key_types[keytype];}const char *ssl_asn1_table_keyfmt(apr_pool_t *p, const char *id, int keytype){ const char *keystr = ssl_asn1_keystr(keytype); return apr_pstrcat(p, id, ":", keystr, NULL);}#if APR_HAS_THREADS/* * To ensure thread-safetyness in OpenSSL - work in progress */static apr_thread_mutex_t **lock_cs;static int lock_num_locks;#ifdef SSLC_VERSION_NUMBER#if SSLC_VERSION_NUMBER >= 0x2000static int ssl_util_thr_lock(int mode, int type, const char *file, int line)#elsestatic void ssl_util_thr_lock(int mode, int type, const char *file, int line)#endif#elsestatic void ssl_util_thr_lock(int mode, int type, const char *file, int line)#endif{ if (type < lock_num_locks) { if (mode & CRYPTO_LOCK) { apr_thread_mutex_lock(lock_cs[type]); } else { apr_thread_mutex_unlock(lock_cs[type]); }#ifdef SSLC_VERSION_NUMBER#if SSLC_VERSION_NUMBER >= 0x2000 return 1; } else { return -1;#endif#endif }}static unsigned long ssl_util_thr_id(void){ /* OpenSSL needs this to return an unsigned long. On OS/390, the pthread * id is a structure twice that big. Use the TCB pointer instead as a * unique unsigned long. */#ifdef __MVS__ struct PSA { char unmapped[540]; unsigned long PSATOLD; } *psaptr = 0; return psaptr->PSATOLD;#else return (unsigned long) apr_os_thread_current();#endif}static apr_status_t ssl_util_thread_cleanup(void *data){ CRYPTO_set_locking_callback(NULL); CRYPTO_set_id_callback(NULL); /* Let the registered mutex cleanups do their own thing */ return APR_SUCCESS;}void ssl_util_thread_setup(apr_pool_t *p){ int i; lock_num_locks = CRYPTO_num_locks(); lock_cs = apr_palloc(p, lock_num_locks * sizeof(*lock_cs)); for (i = 0; i < lock_num_locks; i++) { apr_thread_mutex_create(&(lock_cs[i]), APR_THREAD_MUTEX_DEFAULT, p); } CRYPTO_set_id_callback(ssl_util_thr_id); CRYPTO_set_locking_callback(ssl_util_thr_lock); apr_pool_cleanup_register(p, NULL, ssl_util_thread_cleanup, apr_pool_cleanup_null);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -