diff --git a/ChangeLog b/ChangeLog index b7d1f8231..d9ccc6b82 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,8 @@ Note: Most of these features have been donated by Fox-IT status, objects and configuration + Added verification callback on certificate chain verification to allow external blacklisting + * Added support for PKCS#11 through the use of the + libpkcs11-helper library Changes * x509parse_time_expired() checks time in addition to diff --git a/include/polarssl/config.h b/include/polarssl/config.h index 3b0c7e7ea..ec2864297 100644 --- a/include/polarssl/config.h +++ b/include/polarssl/config.h @@ -319,6 +319,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 000000000..efe7f14be --- /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 + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * 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 + +/** + * 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 7ddf7b1ff..a4d3af0d9 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 @@ struct _ssl_context * 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_ca_chain( ssl_context *ssl, x509_cert *ca_chain, 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) diff --git a/library/Makefile b/library/Makefile index 794512164..a23904d57 100644 --- a/library/Makefile +++ b/library/Makefile @@ -26,7 +26,8 @@ OBJS= aes.o arc4.o base64.o \ ssl_cli.o ssl_srv.o ssl_tls.o \ timing.o x509parse.o xtea.o \ camellia.o version.o md.o \ - md_wrap.o cipher.o cipher_wrap.o + md_wrap.o cipher.o cipher_wrap.o \ + pkcs11.o .SILENT: diff --git a/library/pkcs11.c b/library/pkcs11.c new file mode 100644 index 000000000..172ffc1f6 --- /dev/null +++ b/library/pkcs11.c @@ -0,0 +1,239 @@ +/** + * \file pkcs11.c + * + * \brief Wrapper for PKCS#11 library libpkcs11-helper + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * 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. + */ + +#include "polarssl/pkcs11.h" + +#if defined(POLARSSL_PKCS11_C) + +#include +#include + +int pkcs11_x509_cert_init( x509_cert *cert, pkcs11h_certificate_t pkcs11_cert ) +{ + int ret = 1; + unsigned char *cert_blob = NULL; + size_t cert_blob_size = 0; + + if( cert == NULL ) + { + ret = 2; + goto cleanup; + } + + if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, &cert_blob_size ) != CKR_OK ) + { + ret = 3; + goto cleanup; + } + + cert_blob = malloc( cert_blob_size ); + if( NULL == cert_blob ) + { + ret = 4; + goto cleanup; + } + + if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, &cert_blob_size ) != CKR_OK ) + { + ret = 5; + goto cleanup; + } + + if( 0 != x509parse_crt(cert, cert_blob, cert_blob_size ) ) + { + ret = 6; + goto cleanup; + } + + ret = 0; + +cleanup: + if( NULL != cert_blob ) + free( cert_blob ); + + return ret; +} + + +int pkcs11_priv_key_init( pkcs11_context *priv_key, + pkcs11h_certificate_t pkcs11_cert ) +{ + int ret = 1; + x509_cert cert; + + memset( &cert, 0, sizeof( cert ) ); + + if( priv_key == NULL ) + goto cleanup; + + if( 0 != pkcs11_x509_cert_init( &cert, pkcs11_cert ) ) + goto cleanup; + + priv_key->len = cert.rsa.len; + priv_key->pkcs11h_cert = pkcs11_cert; + + ret = 0; + +cleanup: + x509_free( &cert ); + + return ret; +} + +void pkcs11_priv_key_free( pkcs11_context *priv_key ) +{ + if( NULL != priv_key ) + pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert ); +} + +int pkcs11_decrypt( pkcs11_context *ctx, + int mode, int *olen, + const unsigned char *input, + unsigned char *output, + int output_max_len ) +{ + size_t input_len, output_len; + + if( NULL == ctx ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( RSA_PUBLIC == mode ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + output_len = input_len = ctx->len; + + if( input_len < 16 || input_len > output_max_len ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + /* Determine size of output buffer */ + if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, + input_len, NULL, &output_len ) != CKR_OK ) + { + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + + if( output_len > output_max_len ) + return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE ); + + if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, + input_len, output, &output_len ) != CKR_OK ) + { + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + *olen = output_len; + return( 0 ); +} + +int pkcs11_sign( pkcs11_context *ctx, + int mode, + int hash_id, + int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + size_t olen, asn_len; + unsigned char *p = sig; + + if( NULL == ctx ) + return POLARSSL_ERR_RSA_BAD_INPUT_DATA; + + if( RSA_PUBLIC == mode ) + return POLARSSL_ERR_RSA_BAD_INPUT_DATA; + + olen = ctx->len; + + switch( hash_id ) + { + case SIG_RSA_RAW: + asn_len = 0; + memcpy( p, hash, hashlen ); + break; + + case SIG_RSA_MD2: + asn_len = OID_SIZE(ASN1_HASH_MDX); + memcpy( p, ASN1_HASH_MDX, asn_len ); + memcpy( p + asn_len, hash, hashlen ); + p[13] = 2; break; + + case SIG_RSA_MD4: + asn_len = OID_SIZE(ASN1_HASH_MDX); + memcpy( p, ASN1_HASH_MDX, asn_len ); + memcpy( p + asn_len, hash, hashlen ); + p[13] = 4; break; + + case SIG_RSA_MD5: + asn_len = OID_SIZE(ASN1_HASH_MDX); + memcpy( p, ASN1_HASH_MDX, asn_len ); + memcpy( p + asn_len, hash, hashlen ); + p[13] = 5; break; + + case SIG_RSA_SHA1: + asn_len = OID_SIZE(ASN1_HASH_SHA1); + memcpy( p, ASN1_HASH_SHA1, asn_len ); + memcpy( p + 15, hash, hashlen ); + break; + + case SIG_RSA_SHA224: + asn_len = OID_SIZE(ASN1_HASH_SHA2X); + memcpy( p, ASN1_HASH_SHA2X, asn_len ); + memcpy( p + asn_len, hash, hashlen ); + p[1] += hashlen; p[14] = 4; p[18] += hashlen; break; + + case SIG_RSA_SHA256: + asn_len = OID_SIZE(ASN1_HASH_SHA2X); + memcpy( p, ASN1_HASH_SHA2X, asn_len ); + memcpy( p + asn_len, hash, hashlen ); + p[1] += hashlen; p[14] = 1; p[18] += hashlen; break; + + case SIG_RSA_SHA384: + asn_len = OID_SIZE(ASN1_HASH_SHA2X); + memcpy( p, ASN1_HASH_SHA2X, asn_len ); + memcpy( p + asn_len, hash, hashlen ); + p[1] += hashlen; p[14] = 2; p[18] += hashlen; break; + + case SIG_RSA_SHA512: + asn_len = OID_SIZE(ASN1_HASH_SHA2X); + memcpy( p, ASN1_HASH_SHA2X, asn_len ); + memcpy( p + asn_len, hash, hashlen ); + p[1] += hashlen; p[14] = 3; p[18] += hashlen; break; + + default: + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + + if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig, + asn_len + hashlen, sig, &olen ) != CKR_OK ) + { + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + + return( 0 ); +} + +#endif /* defined(POLARSSL_PKCS11_C) */ diff --git a/library/ssl_cli.c b/library/ssl_cli.c index cebcceb05..b1e5d01b8 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -30,6 +30,10 @@ #include "polarssl/debug.h" #include "polarssl/ssl.h" +#if defined(POLARSSL_PKCS11_C) +#include "polarssl/pkcs11.h" +#endif /* defined(POLARSSL_PKCS11_C) */ + #include #include #include @@ -635,8 +639,15 @@ static int ssl_write_certificate_verify( ssl_context *ssl ) if( ssl->rsa_key == NULL ) { - SSL_DEBUG_MSG( 1, ( "got no private key" ) ); - return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); +#if defined(POLARSSL_PKCS11_C) + if( ssl->pkcs11_key == NULL ) + { +#endif /* defined(POLARSSL_PKCS11_C) */ + SSL_DEBUG_MSG( 1, ( "got no private key" ) ); + return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); +#if defined(POLARSSL_PKCS11_C) + } +#endif /* defined(POLARSSL_PKCS11_C) */ } /* @@ -644,14 +655,30 @@ static int ssl_write_certificate_verify( ssl_context *ssl ) */ ssl_calc_verify( ssl, hash ); - n = ssl->rsa_key->len; + if ( ssl->rsa_key ) + n = ssl->rsa_key->len; +#if defined(POLARSSL_PKCS11_C) + else + n = ssl->pkcs11_key->len; +#endif /* defined(POLARSSL_PKCS11_C) */ + ssl->out_msg[4] = (unsigned char)( n >> 8 ); ssl->out_msg[5] = (unsigned char)( n ); - if( ( ret = rsa_pkcs1_sign( ssl->rsa_key, RSA_PRIVATE, SIG_RSA_RAW, - 36, hash, ssl->out_msg + 6 ) ) != 0 ) + if( ssl->rsa_key ) { - SSL_DEBUG_RET( 1, "rsa_pkcs1_sign", ret ); + ret = rsa_pkcs1_sign( ssl->rsa_key, RSA_PRIVATE, SIG_RSA_RAW, + 36, hash, ssl->out_msg + 6 ); + } else { +#if defined(POLARSSL_PKCS11_C) + ret = pkcs11_sign( ssl->pkcs11_key, RSA_PRIVATE, SIG_RSA_RAW, + 36, hash, ssl->out_msg + 6 ); +#endif /* defined(POLARSSL_PKCS11_C) */ + } + + if (ret != 0) + { + SSL_DEBUG_RET( 1, "pkcs1_sign", ret ); return( ret ); } diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 24b8b4491..f51a2de90 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -30,6 +30,10 @@ #include "polarssl/debug.h" #include "polarssl/ssl.h" +#if defined(POLARSSL_PKCS11_C) +#include "polarssl/pkcs11.h" +#endif /* defined(POLARSSL_PKCS11_C) */ + #include #include #include @@ -521,7 +525,7 @@ static int ssl_write_certificate_request( ssl_context *ssl ) static int ssl_write_server_key_exchange( ssl_context *ssl ) { - int ret, n; + int ret, n, rsa_key_len = 0; unsigned char hash[36]; md5_context md5; sha1_context sha1; @@ -543,6 +547,20 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) SSL_DEBUG_MSG( 1, ( "support for dhm is not available" ) ); return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); #else + + if( ssl->rsa_key == NULL ) + { +#if defined(POLARSSL_PKCS11_C) + if( ssl->pkcs11_key == NULL ) + { +#endif /* defined(POLARSSL_PKCS11_C) */ + SSL_DEBUG_MSG( 1, ( "got no private key" ) ); + return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); +#if defined(POLARSSL_PKCS11_C) + } +#endif /* defined(POLARSSL_PKCS11_C) */ + } + /* * Ephemeral DH parameters: * @@ -589,21 +607,37 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) SSL_DEBUG_BUF( 3, "parameters hash", hash, 36 ); - ssl->out_msg[4 + n] = (unsigned char)( ssl->rsa_key->len >> 8 ); - ssl->out_msg[5 + n] = (unsigned char)( ssl->rsa_key->len ); + if ( ssl->rsa_key ) + rsa_key_len = ssl->rsa_key->len; +#if defined(POLARSSL_PKCS11_C) + else + rsa_key_len = ssl->pkcs11_key->len; +#endif /* defined(POLARSSL_PKCS11_C) */ + + ssl->out_msg[4 + n] = (unsigned char)( rsa_key_len >> 8 ); + ssl->out_msg[5 + n] = (unsigned char)( rsa_key_len ); + + if ( ssl->rsa_key ) + { + ret = rsa_pkcs1_sign( ssl->rsa_key, RSA_PRIVATE, + SIG_RSA_RAW, 36, hash, ssl->out_msg + 6 + n ); + } +#if defined(POLARSSL_PKCS11_C) + else { + ret = pkcs11_sign( ssl->pkcs11_key, RSA_PRIVATE, + SIG_RSA_RAW, 36, hash, ssl->out_msg + 6 + n ); + } +#endif /* defined(POLARSSL_PKCS11_C) */ - ret = rsa_pkcs1_sign( ssl->rsa_key, RSA_PRIVATE, - SIG_RSA_RAW, 36, hash, ssl->out_msg + 6 + n ); if( ret != 0 ) { - SSL_DEBUG_RET( 1, "rsa_pkcs1_sign", ret ); + SSL_DEBUG_RET( 1, "pkcs1_sign", ret ); return( ret ); } - SSL_DEBUG_BUF( 3, "my RSA sig", ssl->out_msg + 6 + n, - ssl->rsa_key->len ); + SSL_DEBUG_BUF( 3, "my RSA sig", ssl->out_msg + 6 + n, rsa_key_len ); - ssl->out_msglen = 6 + n + ssl->rsa_key->len; + ssl->out_msglen = 6 + n + rsa_key_len; ssl->out_msgtype = SSL_MSG_HANDSHAKE; ssl->out_msg[0] = SSL_HS_SERVER_KEY_EXCHANGE; @@ -713,11 +747,29 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) } else { + if( ssl->rsa_key == NULL ) + { +#if defined(POLARSSL_PKCS11_C) + if( ssl->pkcs11_key == NULL ) + { +#endif + SSL_DEBUG_MSG( 1, ( "got no private key" ) ); + return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); +#if defined(POLARSSL_PKCS11_C) + } +#endif + } + /* * Decrypt the premaster using own private RSA key */ i = 4; - n = ssl->rsa_key->len; + if( ssl->rsa_key ) + n = ssl->rsa_key->len; +#if defined(POLARSSL_PKCS11_C) + else + n = ssl->pkcs11_key->len; +#endif ssl->pmslen = 48; if( ssl->minor_ver != SSL_MINOR_VERSION_0 ) @@ -737,9 +789,18 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } - ret = rsa_pkcs1_decrypt( ssl->rsa_key, RSA_PRIVATE, &ssl->pmslen, + if( ssl->rsa_key ) { + ret = rsa_pkcs1_decrypt( ssl->rsa_key, RSA_PRIVATE, &ssl->pmslen, ssl->in_msg + i, ssl->premaster, - sizeof(ssl->premaster) ); + sizeof(ssl->premaster) ); + } +#if defined(POLARSSL_PKCS11_C) + else { + ret = pkcs11_decrypt( ssl->pkcs11_key, RSA_PRIVATE, &ssl->pmslen, + ssl->in_msg + i, ssl->premaster, + sizeof(ssl->premaster) ); + } +#endif /* defined(POLARSSL_PKCS11_C) */ if( ret != 0 || ssl->pmslen != 48 || ssl->premaster[0] != ssl->max_major_ver || diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 4eb0b682c..3856fff0a 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1796,6 +1796,15 @@ void ssl_set_own_cert( ssl_context *ssl, x509_cert *own_cert, ssl->rsa_key = rsa_key; } +#if defined(POLARSSL_PKCS11_C) +void ssl_set_own_cert_pkcs11( ssl_context *ssl, x509_cert *own_cert, + pkcs11_context *pkcs11_key ) +{ + ssl->own_cert = own_cert; + ssl->pkcs11_key = pkcs11_key; +} +#endif + int ssl_set_dh_param( ssl_context *ssl, const char *dhm_P, const char *dhm_G ) { int ret; diff --git a/programs/Makefile b/programs/Makefile index 0e467e698..7ddc4c57d 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -1,6 +1,7 @@ # To compile on SunOS: add "-lsocket -lnsl" to LDFLAGS # To compile on MinGW: add "-lws2_32" to LDFLAGS +# To compile with PKCS11: add "-lpkcs11-helper" to LDFLAGS CFLAGS = -I../include -D_FILE_OFFSET_BITS=64 -Wall -Wdeclaration-after-statement OFLAGS = -O diff --git a/tests/Makefile b/tests/Makefile index 063245b53..aacdcba53 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,6 +1,7 @@ # To compile on SunOS: add "-lsocket -lnsl" to LDFLAGS # To compile on MinGW: add "-lws2_32" to LDFLAGS +# To compile with PKCS11: add "-lpkcs11-helper" to LDFLAGS CFLAGS = -I../include -D_FILE_OFFSET_BITS=64 -Wall -Wdeclaration-after-statement \ -Wno-unused-function -Wno-unused-value