- Support for PKCS#11 through the use of the pkcs11-helper library
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index 3b0c7e7..ec28642 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -320,6 +320,16 @@
#define POLARSSL_SSL_TLS_C
/*
+ * Module: library/ssl_srv.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module is required for SSL/TLS PKCS #11 smartcard support.
+ * Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
+ */
+#define POLARSSL_PKCS11_C
+
+/*
* Module: library/timing.c
* Caller: library/havege.c
*
diff --git a/include/polarssl/pkcs11.h b/include/polarssl/pkcs11.h
new file mode 100644
index 0000000..efe7f14
--- /dev/null
+++ b/include/polarssl/pkcs11.h
@@ -0,0 +1,127 @@
+/**
+ * \file pkcs11.h
+ *
+ * \brief Wrapper for PKCS#11 library libpkcs11-helper
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef PKCS11_H_
+#define PKCS11_H_
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_PKCS11_C)
+
+#include "polarssl/x509.h"
+
+#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
+
+/**
+ * Context for PKCS #11 private keys.
+ */
+typedef struct {
+ pkcs11h_certificate_t pkcs11h_cert;
+ int len;
+} pkcs11_context;
+
+/**
+ * Fill in a PolarSSL certificate, based on the given PKCS11 helper certificate.
+ *
+ * \param cert X.509 certificate to fill
+ * \param pkcs11h_cert PKCS #11 helper certificate
+ *
+ * \return 0 on success.
+ */
+int pkcs11_x509_cert_init( x509_cert *cert, pkcs11h_certificate_t pkcs11h_cert );
+
+/**
+ * Initialise a pkcs11_context, storing the given certificate. Note that the
+ * pkcs11_context will take over control of the certificate, freeing it when
+ * done.
+ *
+ * \param priv_key Private key structure to fill.
+ * \param pkcs11_cert PKCS #11 helper certificate
+ *
+ * \return 0 on success
+ */
+int pkcs11_priv_key_init( pkcs11_context *priv_key,
+ pkcs11h_certificate_t pkcs11_cert );
+
+/**
+ * Free the contents of the given private key context. Note that the structure
+ * itself is not freed.
+ *
+ * \param priv_key Private key structure to cleanup
+ */
+void pkcs11_priv_key_free( pkcs11_context *priv_key );
+
+/**
+ * \brief Do an RSA private key decrypt, then remove the message padding
+ *
+ * \param ctx PKCS #11 context
+ * \param mode must be RSA_PRIVATE, for compatibility with rsa.c's signature
+ * \param input buffer holding the encrypted data
+ * \param output buffer that will hold the plaintext
+ * \param olen will contain the plaintext length
+ * \param output_max_len maximum length of the output buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
+ * an error is thrown.
+ */
+int pkcs11_decrypt( pkcs11_context *ctx,
+ int mode, int *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ int output_max_len );
+
+/**
+ * \brief Do a private RSA to sign a message digest
+ *
+ * \param ctx PKCS #11 context
+ * \param mode must be RSA_PRIVATE, for compatibility with rsa.c's signature
+ * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
+ * \param hashlen message digest length (for SIG_RSA_RAW only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer that will hold the ciphertext
+ *
+ * \return 0 if the signing operation was successful,
+ * or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int pkcs11_sign( pkcs11_context *ctx,
+ int mode,
+ int hash_id,
+ int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+#endif /* POLARSSL_PKCS11_C */
+
+#endif /* PKCS11_H_ */
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 7ddf7b1..a4d3af0 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -35,6 +35,11 @@
#include "polarssl/md5.h"
#include "polarssl/sha1.h"
#include "polarssl/x509.h"
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_PKCS11_C)
+#include "polarssl/pkcs11.h"
+#endif
/*
* SSL Error codes
@@ -268,6 +273,9 @@
* PKI layer
*/
rsa_context *rsa_key; /*!< own RSA private key */
+#if defined(POLARSSL_PKCS11_C)
+ pkcs11_context *pkcs11_key; /*!< own PKCS#11 RSA private key */
+#endif
x509_cert *own_cert; /*!< own X.509 certificate */
x509_cert *ca_chain; /*!< own trusted CA chain */
x509_crl *ca_crl; /*!< trusted CA CRLs */
@@ -480,6 +488,18 @@
void ssl_set_own_cert( ssl_context *ssl, x509_cert *own_cert,
rsa_context *rsa_key );
+#if defined(POLARSSL_PKCS11_C)
+/**
+ * \brief Set own certificate and PKCS#11 private key
+ *
+ * \param ssl SSL context
+ * \param own_cert own public certificate
+ * \param pkcs11_key own PKCS#11 RSA key
+ */
+void ssl_set_own_cert_pkcs11( ssl_context *ssl, x509_cert *own_cert,
+ pkcs11_context *pkcs11_key );
+#endif
+
/**
* \brief Set the Diffie-Hellman public P and G values,
* read as hexadecimal strings (server-side only)