multi.c multi.h \
ntlm.c ntlm.h \
occ.c occ.h occ-inline.h \
- pkcs11.c pkcs11.h \
+ pkcs11.c pkcs11.h pkcs11_backend.h \
openvpn.c openvpn.h \
openvpn-plugin.h \
options.c options.h \
if USE_OPENSSL
openvpn_SOURCES += \
crypto_openssl.c crypto_openssl.h \
+ pkcs11_openssl.c \
ssl_openssl.c ssl_openssl.h \
ssl_verify_openssl.c ssl_verify_openssl.h
endif
#if defined(ENABLE_PKCS11)
#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
-#include <pkcs11-helper-1.0/pkcs11h-openssl.h>
#include "basic.h"
#include "error.h"
#include "manage.h"
#include "pkcs11.h"
#include "misc.h"
#include "otime.h"
+#include "pkcs11_backend.h"
static
time_t
}
int
-SSL_CTX_use_pkcs11 (
- SSL_CTX * const ssl_ctx,
+tls_ctx_use_pkcs11 (
+ struct tls_root_ctx * const ssl_ctx,
bool pkcs11_id_management,
const char * const pkcs11_id
) {
- X509 *x509 = NULL;
- RSA *rsa = NULL;
pkcs11h_certificate_id_t certificate_id = NULL;
pkcs11h_certificate_t certificate = NULL;
- pkcs11h_openssl_session_t openssl_session = NULL;
CK_RV rv = CKR_OK;
bool ok = false;
dmsg (
D_PKCS11_DEBUG,
- "PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
+ "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
(void *)ssl_ctx,
pkcs11_id_management ? 1 : 0,
pkcs11_id
goto cleanup;
}
- if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL ) {
- msg (M_WARN, "PKCS#11: Cannot initialize openssl session");
+ if (
+ (pkcs11_init_tls_session (
+ certificate,
+ ssl_ctx
+ ))
+ ) {
+ /* Handled by SSL context free */
+ certificate = NULL;
goto cleanup;
}
- /*
- * Will be released by openssl_session
- */
+ /* Handled by SSL context free */
certificate = NULL;
-
- if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL) {
- msg (M_WARN, "PKCS#11: Unable get rsa object");
- goto cleanup;
- }
-
- if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) {
- msg (M_WARN, "PKCS#11: Unable get certificate object");
- goto cleanup;
- }
-
- if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)) {
- msg (M_WARN, "PKCS#11: Cannot set private key for openssl");
- goto cleanup;
- }
-
- if (!SSL_CTX_use_certificate (ssl_ctx, x509)) {
- msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
- goto cleanup;
- }
-
ok = true;
cleanup:
- /*
- * openssl objects have reference
- * count, so release them
- */
-
- if (x509 != NULL) {
- X509_free (x509);
- x509 = NULL;
- }
-
- if (rsa != NULL) {
- RSA_free (rsa);
- rsa = NULL;
- }
-
if (certificate != NULL) {
pkcs11h_certificate_freeCertificate (certificate);
certificate = NULL;
pkcs11h_certificate_freeCertificateId (certificate_id);
certificate_id = NULL;
}
-
- if (openssl_session != NULL) {
- pkcs11h_openssl_freeSession (openssl_session);
- openssl_session = NULL;
- }
dmsg (
D_PKCS11_DEBUG,
- "PKCS#11: SSL_CTX_use_pkcs11 - return ok=%d, rv=%ld",
+ "PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld",
ok ? 1 : 0,
rv
);
);
for (current = user_certificates;current != NULL; current = current->next) {
pkcs11h_certificate_t certificate = NULL;
- X509 *x509 = NULL;
- BIO *bio = NULL;
char dn[1024] = {0};
char serial[1024] = {0};
char *ser = NULL;
size_t ser_len = 0;
- int n;
if (
(rv = pkcs11h_certificate_serializeCertificateId (
goto cleanup1;
}
- if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL) {
- msg (M_FATAL, "PKCS#11: Cannot get X509");
+ if (
+ (pkcs11_certificate_dn (
+ certificate,
+ dn,
+ sizeof(dn)
+ ))
+ ) {
goto cleanup1;
}
- X509_NAME_oneline (
- X509_get_subject_name (x509),
- dn,
- sizeof (dn)
- );
-
- if ((bio = BIO_new (BIO_s_mem ())) == NULL) {
- msg (M_FATAL, "PKCS#11: Cannot create BIO");
+ if (
+ (pkcs11_certificate_serial (
+ certificate,
+ serial,
+ sizeof(serial)
+ ))
+ ) {
goto cleanup1;
}
- i2a_ASN1_INTEGER(bio, X509_get_serialNumber (x509));
- n = BIO_read (bio, serial, sizeof (serial)-1);
- if (n<0) {
- serial[0] = '\x0';
- }
- else {
- serial[n] = 0;
- }
-
msg (
M_INFO|M_NOPREFIX|M_NOLF,
(
);
cleanup1:
- if (x509 != NULL) {
- X509_free (x509);
- x509 = NULL;
- }
if (certificate != NULL) {
pkcs11h_certificate_freeCertificate (certificate);
#if defined(ENABLE_PKCS11)
-#include <openssl/ssl.h>
+#include "ssl_common.h"
bool
pkcs11_initialize (
);
int
-SSL_CTX_use_pkcs11 (
- SSL_CTX * const ssl_ctx,
+tls_ctx_use_pkcs11 (
+ struct tls_root_ctx * const ssl_ctx,
bool pkcs11_id_management,
const char * const pkcs11_id
);
--- /dev/null
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**
+ * @file PKCS #11 SSL library-specific backend
+ */
+
+#ifndef PKCS11_BACKEND_H_
+#define PKCS11_BACKEND_H_
+
+#include "syshead.h"
+
+#if defined(ENABLE_PKCS11)
+
+#include "ssl_common.h"
+
+#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
+
+/**
+ * Retrieve PKCS #11 Certificate's DN in a printable format.
+ *
+ * @param certificate The PKCS #11 helper certificate object
+ * @param dn Buffer that the certificate subject DN will be placed in.
+ * @param dn_len Size of said buffer.
+ *
+ * @return 1 on failure, 0 on success
+ */
+int pkcs11_certificate_dn (pkcs11h_certificate_t certificate, char *dn,
+ size_t dn_len);
+
+/**
+ * Retrieve PKCS #11 Certificate's serial number in a printable format.
+ *
+ * @param certificate The PKCS #11 helper certificate object
+ * @param serial Buffer that the certificate's serial will be placed in.
+ * @param serial_len Size of said buffer.
+ *
+ * @return 1 on failure, 0 on success
+ */
+int pkcs11_certificate_serial (pkcs11h_certificate_t certificate, char *serial,
+ size_t serial_len);
+
+/**
+ * Load PKCS #11 Certificate's information into the given TLS context
+ *
+ * @param certificate The PKCS #11 helper certificate object
+ * @param ssl_ctx TLS context to use.
+ *
+ * @return 1 on failure, 0 on success
+ */
+int pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
+ struct tls_root_ctx * const ssl_ctx);
+
+#endif /* defined(ENABLE_PKCS11) */
+#endif /* PKCS11_BACKEND_H_ */
--- /dev/null
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**
+ * @file PKCS #11 OpenSSL backend
+ */
+
+#include "syshead.h"
+
+#ifdef ENABLE_PKCS11
+
+#include "errlevel.h"
+#include "pkcs11_backend.h"
+#include <pkcs11-helper-1.0/pkcs11h-openssl.h>
+
+int
+pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
+ struct tls_root_ctx * const ssl_ctx)
+{
+ int ret = 1;
+
+ X509 *x509 = NULL;
+ RSA *rsa = NULL;
+ pkcs11h_openssl_session_t openssl_session = NULL;
+
+ if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL)
+ {
+ msg (M_WARN, "PKCS#11: Cannot initialize openssl session");
+ goto cleanup;
+ }
+
+ /*
+ * Will be released by openssl_session
+ */
+ certificate = NULL;
+
+ if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL)
+ {
+ msg (M_WARN, "PKCS#11: Unable get rsa object");
+ goto cleanup;
+ }
+
+ if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL)
+ {
+ msg (M_WARN, "PKCS#11: Unable get certificate object");
+ goto cleanup;
+ }
+
+ if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx->ctx, rsa))
+ {
+ msg (M_WARN, "PKCS#11: Cannot set private key for openssl");
+ goto cleanup;
+ }
+
+ if (!SSL_CTX_use_certificate (ssl_ctx->ctx, x509))
+ {
+ msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
+ goto cleanup;
+ }
+ ret = 0;
+
+cleanup:
+ /*
+ * Certificate freeing is usually handled by openssl_session.
+ * If something went wrong, creating the session we have to do it manually.
+ */
+ if (certificate != NULL) {
+ pkcs11h_certificate_freeCertificate (certificate);
+ certificate = NULL;
+ }
+
+ /*
+ * openssl objects have reference
+ * count, so release them
+ */
+ if (x509 != NULL)
+ {
+ X509_free (x509);
+ x509 = NULL;
+ }
+
+ if (rsa != NULL)
+ {
+ RSA_free (rsa);
+ rsa = NULL;
+ }
+
+ if (openssl_session != NULL)
+ {
+ pkcs11h_openssl_freeSession (openssl_session);
+ openssl_session = NULL;
+ }
+ return ret;
+}
+
+int
+pkcs11_certificate_dn (pkcs11h_certificate_t certificate, char *dn,
+ size_t dn_len)
+{
+ X509 *x509 = NULL;
+ int ret = 1;
+
+ if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL)
+ {
+ msg (M_FATAL, "PKCS#11: Cannot get X509");
+ ret = 1;
+ goto cleanup;
+ }
+
+ X509_NAME_oneline (X509_get_subject_name (x509), dn, dn_len);
+
+ ret = 0;
+
+cleanup:
+ if (x509 != NULL)
+ {
+ X509_free (x509);
+ x509 = NULL;
+ }
+
+ return ret;
+}
+
+int
+pkcs11_certificate_serial (pkcs11h_certificate_t certificate, char *serial,
+ size_t serial_len)
+{
+ X509 *x509 = NULL;
+ BIO *bio = NULL;
+ int ret = 1;
+ int n;
+
+ if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL)
+ {
+ msg (M_FATAL, "PKCS#11: Cannot get X509");
+ goto cleanup;
+ }
+
+ if ((bio = BIO_new (BIO_s_mem ())) == NULL)
+ {
+ msg (M_FATAL, "PKCS#11: Cannot create BIO");
+ goto cleanup;
+ }
+
+ i2a_ASN1_INTEGER(bio, X509_get_serialNumber (x509));
+ n = BIO_read (bio, serial, serial_len-1);
+
+ if (n<0) {
+ serial[0] = '\x0';
+ }
+ else {
+ serial[n] = 0;
+ }
+
+ ret = 0;
+
+cleanup:
+
+ if (x509 != NULL)
+ {
+ X509_free (x509);
+ x509 = NULL;
+ }
+ return ret;
+}
+#endif /* ENABLE_PKCS11 */
#ifdef ENABLE_PKCS11
else if (options->pkcs11_providers[0])
{
- if (0 != tls_ctx_load_pkcs11(new_ctx, options->pkcs11_id_management, options->pkcs11_id))
- goto err;
+ if (!tls_ctx_use_pkcs11 (new_ctx, options->pkcs11_id_management, options->pkcs11_id))
+ {
+ msg (M_WARN, "Cannot load certificate \"%s\" using PKCS#11 interface",
+ options->pkcs11_id);
+ goto err;
+ }
}
#endif
#ifdef WIN32
bool load_ca_file
);
-/*
- * Load PKCS #11 information for key and cert, and add to library-specific TLS
- * context.
- *
- * TODO: document
- */
-#ifdef ENABLE_PKCS11
-int tls_ctx_load_pkcs11(struct tls_root_ctx *ctx,
- bool pkcs11_id_management, const char *pkcs11_id);
-#endif /* ENABLE_PKCS11 */
-
/**
* Use Windows cryptoapi for key and cert, and add to library-specific TLS
* context.
return 0;
}
-#ifdef ENABLE_PKCS11
-int
-tls_ctx_load_pkcs11(struct tls_root_ctx *ctx, bool pkcs11_id_management,
- const char *pkcs11_id)
-{
- ASSERT(NULL != ctx);
-
- /* Load Certificate and Private Key */
- if (!SSL_CTX_use_pkcs11 (ctx->ctx, pkcs11_id_management, pkcs11_id))
- {
- msg (M_WARN, "Cannot load certificate \"%s\" using PKCS#11 interface", pkcs11_id);
- return 1;
- }
- return 0;
-}
-#endif /* ENABLE_PKCS11 */
-
#ifdef WIN32
void
tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert)