SSL_CMD_SRV(CertificateChainFile, TAKE1,
"SSL Server CA Certificate Chain file "
"(`/path/to/file' - PEM encoded)")
+ SSL_CMD_SRV(PKCS7CertificateFile, TAKE1,
+ "PKCS#7 file containing server certificate and chain"
+ " certificates (`/path/to/file' - PEM ecnoded)")
SSL_CMD_ALL(CACertificatePath, TAKE1,
"SSL CA Certificate path "
"(`/path/to/dir' - contains PEM encoded files)")
return NULL;
}
+const char *ssl_cmd_SSLPKCS7CertificateFile(cmd_parms *cmd,
+ void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ const char *err;
+
+ if ((err = ssl_cmd_check_file(cmd, &arg))) {
+ return err;
+ }
+
+ sc->server->pkcs7 = arg;
+
+ return NULL;
+}
+
#define NO_PER_DIR_SSL_CA \
"Your ssl library does not have support for per-directory CA"
* check for important parameters and the
* possibility that the user forgot to set them.
*/
- if (!mctx->pks->cert_files[0]) {
+ if (!mctx->pks->cert_files[0] && !mctx->pkcs7) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
"No SSL Certificate set [hint: SSLCertificateFile]");
ssl_die();
}
}
+static void ssl_init_ctx_pkcs7_cert_chain(server_rec *s,modssl_ctx_t *mctx)
+{
+ STACK_OF(X509) *certs=ssl_read_pkcs7(s, mctx->pkcs7);
+ int n;
+
+ if (!mctx->ssl_ctx->extra_certs)
+ for (n = 1; n < sk_X509_num(certs); ++n)
+ SSL_CTX_add_extra_chain_cert(mctx->ssl_ctx, sk_X509_value(certs, n));
+}
+
static void ssl_init_ctx_cert_chain(server_rec *s,
apr_pool_t *p,
apr_pool_t *ptemp,
int i, n;
const char *chain = mctx->cert_chain;
+ if (mctx->pkcs7) {
+ ssl_init_ctx_pkcs7_cert_chain(s,mctx);
+ return;
+ }
+
/*
* Optionally configure extra server certificate chain certificates.
* This is usually done by OpenSSL automatically when one of the
* Read in server certificate(s): This is the easy part
* because this file isn't encrypted in any way.
*/
- if (sc->server->pks->cert_files[0] == NULL) {
+ if (sc->server->pks->cert_files[0] == NULL
+ && sc->server->pkcs7 == NULL) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, pServ,
"Server should be SSL-aware but has no certificate "
"configured [Hint: SSLCertificateFile]");
ssl_die();
}
+
algoCert = SSL_ALGO_UNKNOWN;
algoKey = SSL_ALGO_UNKNOWN;
- for (i = 0, j = 0; i < SSL_AIDX_MAX && sc->server->pks->cert_files[i] != NULL; i++) {
-
- apr_cpystrn(szPath, sc->server->pks->cert_files[i], sizeof(szPath));
- if ((rv = exists_and_readable(szPath, p, NULL)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "Init: Can't open server certificate file %s",
- szPath);
- ssl_die();
- }
- if ((pX509Cert = SSL_read_X509(szPath, NULL, NULL)) == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "Init: Unable to read server certificate from file %s", szPath);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
- ssl_die();
- }
-
+ for (i = 0, j = 0; i < SSL_AIDX_MAX
+ && (sc->server->pks->cert_files[i] != NULL
+ || sc->server->pkcs7); i++) {
+ if (sc->server->pkcs7) {
+ STACK_OF(X509) *certs = ssl_read_pkcs7(pServ, sc->server->pkcs7);
+
+ pX509Cert = sk_X509_value(certs, 0);
+ i = SSL_AIDX_MAX;
+ } else {
+ apr_cpystrn(szPath, sc->server->pks->cert_files[i], sizeof(szPath));
+ if ((rv = exists_and_readable(szPath, p, NULL)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+ "Init: Can't open server certificate file %s",
+ szPath);
+ ssl_die();
+ }
+ if ((pX509Cert = SSL_read_X509(szPath, NULL, NULL)) == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "Init: Unable to read server certificate from file %s", szPath);
+ ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_die();
+ }
+ }
/*
* check algorithm type of certificate and make
* sure only one certificate per type is used.
const char *pphrase_dialog_path;
const char *cert_chain;
+ const char *pkcs7;
/** certificate revocation list */
const char *crl_path;
const char *ssl_cmd_SSLCertificateFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLPKCS7CertificateFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCACertificatePath(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCACertificateFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *, void *, const char *);
const char *ssl_asn1_table_keyfmt(apr_pool_t *p,
const char *id,
int keytype);
+
+STACK_OF(X509) *ssl_read_pkcs7(server_rec *s, const char *pkcs7);
+
/** Mutex Support */
int ssl_mutex_init(server_rec *, apr_pool_t *);
int ssl_mutex_reinit(server_rec *, apr_pool_t *);
return apr_pstrcat(p, id, ":", keystr, NULL);
}
+STACK_OF(X509) *ssl_read_pkcs7(server_rec *s,const char *pkcs7)
+{
+ PKCS7 *p7;
+ STACK_OF(X509) *certs;
+ FILE *f;
+
+ f = fopen(pkcs7, "r");
+ if (!f) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Can't open %s", pkcs7);
+ ssl_die();
+ }
+
+ p7 = PEM_read_PKCS7(f,NULL,NULL,NULL);
+ if (!p7) {
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s,
+ "Can't read PKCS7 object %s", pkcs7);
+ ssl_log_ssl_error(APLOG_MARK, APLOG_CRIT, s);
+ exit(1);
+ }
+
+ switch (OBJ_obj2nid(p7->type)) {
+ case NID_pkcs7_signed:
+ certs = p7->d.sign->cert;
+ break;
+
+ case NID_pkcs7_signedAndEnveloped:
+ certs = p7->d.signed_and_enveloped->cert;
+ break;
+
+ default:
+ ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_NOERRNO, 0, s,
+ "Don't understand PKCS7 file %s", pkcs7);
+ ssl_die();
+ }
+
+ if (!certs) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_NOERRNO, 0, s,
+ "No certificates in %s", pkcs7);
+ ssl_die();
+ }
+
+ return certs;
+}
+
#if APR_HAS_THREADS
/*