Skip to content

Instantly share code, notes, and snippets.

@andj
Created August 11, 2011 15:47
Show Gist options
  • Save andj/1139976 to your computer and use it in GitHub Desktop.
Save andj/1139976 to your computer and use it in GitHub Desktop.
--- /tmp/removed123.txt 2011-08-11 17:43:26.059798588 +0200
+++ /tmp/added123.txt 2011-08-11 17:47:01.037233466 +0200
@@ -1,75 +1,176 @@
--- a/Makefile.am
- pkcs11.c pkcs11.h \
--- a/pkcs11.c
+++ b/Makefile.am
+ pkcs11.c pkcs11.h pkcs11_backend.h \
+ pkcs11_openssl.c \
+++ b/pkcs11_openssl.c
+/*
+ * 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>
-SSL_CTX_use_pkcs11 (
- SSL_CTX * const ssl_ctx,
+
+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;
- "PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
- if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == 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) {
+ 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) {
+ 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)) {
+ 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, x509)) {
+ 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) {
+ if (x509 != NULL)
+ {
X509_free (x509);
x509 = NULL;
}
- if (rsa != NULL) {
+ if (rsa != NULL)
+ {
RSA_free (rsa);
rsa = NULL;
}
-
- if (openssl_session != NULL) {
+ if (openssl_session != NULL)
+ {
pkcs11h_openssl_freeSession (openssl_session);
openssl_session = NULL;
}
- "PKCS#11: SSL_CTX_use_pkcs11 - return ok=%d, rv=%ld",
+ 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) {
+
+ if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL)
+ {
msg (M_FATAL, "PKCS#11: Cannot get X509");
- X509_NAME_oneline (
- X509_get_subject_name (x509),
- dn,
- sizeof (dn)
- );
+ goto cleanup;
+ }
- if ((bio = BIO_new (BIO_s_mem ())) == NULL) {
+ 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, sizeof (serial)-1);
+ n = BIO_read (bio, serial, serial_len-1);
+
if (n<0) {
serial[0] = '\x0';
}
@@ -77,46 +178,136 @@
serial[n] = 0;
}
- if (x509 != NULL) {
+ ret = 0;
+
+cleanup:
+
+ if (x509 != NULL)
+ {
X509_free (x509);
x509 = NULL;
}
--- a/pkcs11.h
-#include <openssl/ssl.h>
-SSL_CTX_use_pkcs11 (
- SSL_CTX * const ssl_ctx,
--- /dev/null
--- /dev/null
--- a/ssl.c
- if (0 != tls_ctx_load_pkcs11(new_ctx, options->pkcs11_id_management, options->pkcs11_id))
- goto err;
--- a/ssl_backend.h
+ return ret;
+}
+#endif /* ENABLE_PKCS11 */
+++ b/pkcs11.c
+#include "pkcs11_backend.h"
+tls_ctx_use_pkcs11 (
+ struct tls_root_ctx * const ssl_ctx,
+ "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
+ if (
+ (pkcs11_init_tls_session (
+ certificate,
+ ssl_ctx
+ ))
+ ) {
+ /* Handled by SSL context free */
+ certificate = NULL;
+ /* Handled by SSL context free */
+ "PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld",
+ if (
+ (pkcs11_certificate_dn (
+ certificate,
+ dn,
+ sizeof(dn)
+ ))
+ ) {
+ if (
+ (pkcs11_certificate_serial (
+ certificate,
+ serial,
+ sizeof(serial)
+ ))
+ ) {
+++ b/pkcs11.h
+#include "ssl_common.h"
+tls_ctx_use_pkcs11 (
+ struct tls_root_ctx * const ssl_ctx,
+++ b/pkcs11_backend.h
/*
- * Load PKCS #11 information for key and cert, and add to library-specific TLS
- * context.
+ * 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.
*
- * TODO: document
+ * 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
*/
-#ifdef ENABLE_PKCS11
-int tls_ctx_load_pkcs11(struct tls_root_ctx *ctx,
- bool pkcs11_id_management, const char *pkcs11_id);
-#endif /* ENABLE_PKCS11 */
--- a/ssl_openssl.c
-#ifdef ENABLE_PKCS11
-int
-tls_ctx_load_pkcs11(struct tls_root_ctx *ctx, bool pkcs11_id_management,
- const char *pkcs11_id)
-{
- ASSERT(NULL != ctx);
+/**
+ * @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);
- /* Load Certificate and Private Key */
- if (!SSL_CTX_use_pkcs11 (ctx->ctx, pkcs11_id_management, pkcs11_id))
+/**
+ * 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_ */
+
+++ b/ssl.c
+ 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", pkcs11_id);
- return 1;
- }
- return 0;
+ msg (M_WARN, "Cannot load certificate \"%s\" using PKCS#11 interface",
+ options->pkcs11_id);
+ goto err;
}
-#endif /* ENABLE_PKCS11 */
-
+++ b/ssl_backend.h
+++ b/ssl_openssl.c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment