- Support for PKCS#11 through the use of the pkcs11-helper library
This commit is contained in:
parent
0f5f72e949
commit
43b7e35b25
11 changed files with 517 additions and 19 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
127
include/polarssl/pkcs11.h
Normal file
127
include/polarssl/pkcs11.h
Normal file
|
@ -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_ */
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
239
library/pkcs11.c
Normal file
239
library/pkcs11.c
Normal file
|
@ -0,0 +1,239 @@
|
|||
/**
|
||||
* \file pkcs11.c
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#include "polarssl/pkcs11.h"
|
||||
|
||||
#if defined(POLARSSL_PKCS11_C)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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) */
|
|
@ -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 <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue