OpenVPN
pkcs11_openssl.c
Go to the documentation of this file.
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-2018 OpenVPN Inc <sales@openvpn.net>
9  * Copyright (C) 2010-2018 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 along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #elif defined(_MSC_VER)
32 #include "config-msvc.h"
33 #endif
34 
35 #include "syshead.h"
36 
37 #if defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_OPENSSL)
38 
39 #include "errlevel.h"
40 #include "pkcs11_backend.h"
41 #include "ssl_verify.h"
42 #include <pkcs11-helper-1.0/pkcs11h-openssl.h>
43 
44 int
45 pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
46  struct tls_root_ctx *const ssl_ctx)
47 {
48  int ret = 1;
49 
50  X509 *x509 = NULL;
51  EVP_PKEY *evp = NULL;
52  pkcs11h_openssl_session_t openssl_session = NULL;
53 
54  if ((openssl_session = pkcs11h_openssl_createSession(certificate)) == NULL)
55  {
56  msg(M_WARN, "PKCS#11: Cannot initialize openssl session");
57  goto cleanup;
58  }
59 
60  /*
61  * Will be released by openssl_session
62  */
63  certificate = NULL;
64 
65  if ((evp = pkcs11h_openssl_session_getEVP(openssl_session)) == NULL)
66  {
67  msg(M_WARN, "PKCS#11: Unable get evp object");
68  goto cleanup;
69  }
70 
71  if ((x509 = pkcs11h_openssl_session_getX509(openssl_session)) == NULL)
72  {
73  msg(M_WARN, "PKCS#11: Unable get certificate object");
74  goto cleanup;
75  }
76 
77  if (!SSL_CTX_use_PrivateKey(ssl_ctx->ctx, evp))
78  {
79  msg(M_WARN, "PKCS#11: Cannot set private key for openssl");
80  goto cleanup;
81  }
82 
83  if (!SSL_CTX_use_certificate(ssl_ctx->ctx, x509))
84  {
85  msg(M_WARN, "PKCS#11: Cannot set certificate for openssl");
86  goto cleanup;
87  }
88  ret = 0;
89 
90 cleanup:
91  /*
92  * Certificate freeing is usually handled by openssl_session.
93  * If something went wrong, creating the session we have to do it manually.
94  */
95  if (certificate != NULL)
96  {
97  pkcs11h_certificate_freeCertificate(certificate);
98  certificate = NULL;
99  }
100 
101  /*
102  * openssl objects have reference
103  * count, so release them
104  */
105  if (x509 != NULL)
106  {
107  X509_free(x509);
108  x509 = NULL;
109  }
110 
111  if (evp != NULL)
112  {
113  EVP_PKEY_free(evp);
114  evp = NULL;
115  }
116 
117  if (openssl_session != NULL)
118  {
119  pkcs11h_openssl_freeSession(openssl_session);
120  openssl_session = NULL;
121  }
122  return ret;
123 }
124 
125 char *
126 pkcs11_certificate_dn(pkcs11h_certificate_t certificate, struct gc_arena *gc)
127 {
128  X509 *x509 = NULL;
129 
130  char *dn = NULL;
131 
132  if ((x509 = pkcs11h_openssl_getX509(certificate)) == NULL)
133  {
134  msg(M_FATAL, "PKCS#11: Cannot get X509");
135  goto cleanup;
136  }
137 
138  dn = x509_get_subject(x509, gc);
139 
140 cleanup:
141  if (x509 != NULL)
142  {
143  X509_free(x509);
144  x509 = NULL;
145  }
146 
147  return dn;
148 }
149 
150 int
151 pkcs11_certificate_serial(pkcs11h_certificate_t certificate, char *serial,
152  size_t serial_len)
153 {
154  X509 *x509 = NULL;
155  BIO *bio = NULL;
156  int ret = 1;
157  int n;
158 
159  if ((x509 = pkcs11h_openssl_getX509(certificate)) == NULL)
160  {
161  msg(M_FATAL, "PKCS#11: Cannot get X509");
162  goto cleanup;
163  }
164 
165  if ((bio = BIO_new(BIO_s_mem())) == NULL)
166  {
167  msg(M_FATAL, "PKCS#11: Cannot create BIO");
168  goto cleanup;
169  }
170 
171  i2a_ASN1_INTEGER(bio, X509_get_serialNumber(x509));
172  n = BIO_read(bio, serial, serial_len-1);
173 
174  if (n<0)
175  {
176  serial[0] = '\x0';
177  }
178  else
179  {
180  serial[n] = 0;
181  }
182 
183  ret = 0;
184 
185 cleanup:
186 
187  if (x509 != NULL)
188  {
189  X509_free(x509);
190  x509 = NULL;
191  }
192  return ret;
193 }
194 #endif /* defined(ENABLE_PKCS11) && defined(ENABLE_OPENSSL) */
char * x509_get_subject(openvpn_x509_cert_t *cert, struct gc_arena *gc)
#define msg
Definition: error.h:173
SSL_CTX * ctx
Definition: ssl_openssl.h:39
Structure that wraps the TLS context.
Definition: ssl_mbedtls.h:90
#define M_FATAL
Definition: error.h:94
#define M_WARN
Definition: error.h:96
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116