1/*
2 *  OpenVPN -- An application to securely tunnel IP networks
3 *             over a single TCP/UDP port, with support for SSL/TLS-based
4 *             session authentication and key exchange,
5 *             packet encryption, packet authentication, and
6 *             packet compression.
7 *
8 *  Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
9 *  Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com>
10 *
11 *  This program is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License version 2
13 *  as published by the Free Software Foundation.
14 *
15 *  This program is distributed in the hope that it will be useful,
16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *  GNU General Public License for more details.
19 *
20 *  You should have received a copy of the GNU General Public License
21 *  along with this program (see the file COPYING included with this
22 *  distribution); if not, write to the Free Software Foundation, Inc.,
23 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 */
25
26/**
27 * @file PKCS #11 PolarSSL backend
28 */
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#elif defined(_MSC_VER)
33#include "config-msvc.h"
34#endif
35
36#include "syshead.h"
37
38#if defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_POLARSSL)
39
40#include "errlevel.h"
41#include "pkcs11_backend.h"
42#include <polarssl/pkcs11.h>
43
44int
45pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
46    struct tls_root_ctx * const ssl_ctx)
47{
48  int ret = 1;
49
50  ASSERT (NULL != ssl_ctx);
51
52  if (pkcs11_x509_cert_init(ssl_ctx->crt_chain, certificate)) {
53      msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object");
54      goto cleanup;
55  }
56
57  ssl_ctx->priv_key_pkcs11 = malloc(sizeof(pkcs11_context));
58
59  if (ssl_ctx->priv_key_pkcs11 == NULL) {
60      msg (M_FATAL, "PKCS#11: Cannot allocate PolarSSL private key object");
61      goto cleanup;
62  }
63
64  if (pkcs11_priv_key_init(ssl_ctx->priv_key_pkcs11, certificate)) {
65      msg (M_FATAL, "PKCS#11: Cannot initialize PolarSSL private key object");
66      goto cleanup;
67  }
68
69  ret = 0;
70
71cleanup:
72  return ret;
73}
74
75char *
76pkcs11_certificate_dn (pkcs11h_certificate_t cert, struct gc_arena *gc)
77{
78  char *ret = NULL;
79  char dn[1024] = {0};
80
81  x509_cert polar_cert = {0};
82
83  if (pkcs11_x509_cert_init(&polar_cert, cert)) {
84      msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object");
85      goto cleanup;
86  }
87
88  if (-1 == x509parse_dn_gets (dn, sizeof(dn), &polar_cert.subject)) {
89      msg (M_FATAL, "PKCS#11: PolarSSL cannot parse subject");
90      goto cleanup;
91  }
92
93  ret = string_alloc(dn, gc);
94
95cleanup:
96  x509_free(&polar_cert);
97
98  return ret;
99}
100
101int
102pkcs11_certificate_serial (pkcs11h_certificate_t cert, char *serial,
103    size_t serial_len)
104{
105  int ret = 1;
106
107  x509_cert polar_cert = {0};
108
109  if (pkcs11_x509_cert_init(&polar_cert, cert)) {
110      msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object");
111      goto cleanup;
112  }
113
114  if (-1 == x509parse_serial_gets (serial, serial_len, &polar_cert.serial)) {
115      msg (M_FATAL, "PKCS#11: PolarSSL cannot parse serial");
116      goto cleanup;
117  }
118
119  ret = 0;
120
121cleanup:
122  x509_free(&polar_cert);
123
124  return ret;
125}
126#endif /* defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_POLARSSL) */
127