PolarSSL v1.3.3
pkcs11.c
Go to the documentation of this file.
1 
30 #include "polarssl/pkcs11.h"
31 
32 #if defined(POLARSSL_PKCS11_C)
33 #include "polarssl/md.h"
34 #include "polarssl/oid.h"
35 #include "polarssl/x509_crt.h"
36 
37 #if defined(POLARSSL_MEMORY_C)
38 #include "polarssl/memory.h"
39 #else
40 #define polarssl_malloc malloc
41 #define polarssl_free free
42 #endif
43 
44 #include <stdlib.h>
45 
46 int pkcs11_x509_cert_init( x509_crt *cert, pkcs11h_certificate_t pkcs11_cert )
47 {
48  int ret = 1;
49  unsigned char *cert_blob = NULL;
50  size_t cert_blob_size = 0;
51 
52  if( cert == NULL )
53  {
54  ret = 2;
55  goto cleanup;
56  }
57 
58  if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, &cert_blob_size ) != CKR_OK )
59  {
60  ret = 3;
61  goto cleanup;
62  }
63 
64  cert_blob = polarssl_malloc( cert_blob_size );
65  if( NULL == cert_blob )
66  {
67  ret = 4;
68  goto cleanup;
69  }
70 
71  if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, &cert_blob_size ) != CKR_OK )
72  {
73  ret = 5;
74  goto cleanup;
75  }
76 
77  if( 0 != x509_crt_parse(cert, cert_blob, cert_blob_size ) )
78  {
79  ret = 6;
80  goto cleanup;
81  }
82 
83  ret = 0;
84 
85 cleanup:
86  if( NULL != cert_blob )
87  polarssl_free( cert_blob );
88 
89  return ret;
90 }
91 
92 
93 int pkcs11_priv_key_init( pkcs11_context *priv_key,
94  pkcs11h_certificate_t pkcs11_cert )
95 {
96  int ret = 1;
97  x509_crt cert;
98 
99  x509_crt_init( &cert );
100 
101  if( priv_key == NULL )
102  goto cleanup;
103 
104  if( 0 != pkcs11_x509_cert_init( &cert, pkcs11_cert ) )
105  goto cleanup;
106 
107  priv_key->len = pk_get_len(&cert.pk);
108  priv_key->pkcs11h_cert = pkcs11_cert;
109 
110  ret = 0;
111 
112 cleanup:
113  x509_crt_free( &cert );
114 
115  return ret;
116 }
117 
118 void pkcs11_priv_key_free( pkcs11_context *priv_key )
119 {
120  if( NULL != priv_key )
121  pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
122 }
123 
124 int pkcs11_decrypt( pkcs11_context *ctx,
125  int mode, size_t *olen,
126  const unsigned char *input,
127  unsigned char *output,
128  size_t output_max_len )
129 {
130  size_t input_len, output_len;
131 
132  if( NULL == ctx )
134 
135  if( RSA_PRIVATE != mode )
137 
138  output_len = input_len = ctx->len;
139 
140  if( input_len < 16 || input_len > output_max_len )
142 
143  /* Determine size of output buffer */
144  if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
145  input_len, NULL, &output_len ) != CKR_OK )
146  {
148  }
149 
150  if( output_len > output_max_len )
152 
153  if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
154  input_len, output, &output_len ) != CKR_OK )
155  {
157  }
158  *olen = output_len;
159  return( 0 );
160 }
161 
162 int pkcs11_sign( pkcs11_context *ctx,
163  int mode,
164  md_type_t md_alg,
165  unsigned int hashlen,
166  const unsigned char *hash,
167  unsigned char *sig )
168 {
169  size_t olen, asn_len = 0, oid_size = 0;
170  unsigned char *p = sig;
171  const char *oid;
172 
173  if( NULL == ctx )
175 
176  if( RSA_PRIVATE != mode )
178 
179  olen = ctx->len;
180 
181  if( md_alg != POLARSSL_MD_NONE )
182  {
183  const md_info_t *md_info = md_info_from_type( md_alg );
184  if( md_info == NULL )
186 
187  if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
189 
190  hashlen = md_get_size( md_info );
191  }
192 
193  if( md_alg == POLARSSL_MD_NONE )
194  {
195  memcpy( p, hash, hashlen );
196  }
197  else
198  {
199  /*
200  * DigestInfo ::= SEQUENCE {
201  * digestAlgorithm DigestAlgorithmIdentifier,
202  * digest Digest }
203  *
204  * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
205  *
206  * Digest ::= OCTET STRING
207  */
209  *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
211  *p++ = (unsigned char) ( 0x04 + oid_size );
212  *p++ = ASN1_OID;
213  *p++ = oid_size & 0xFF;
214  memcpy( p, oid, oid_size );
215  p += oid_size;
216  *p++ = ASN1_NULL;
217  *p++ = 0x00;
218  *p++ = ASN1_OCTET_STRING;
219  *p++ = hashlen;
220 
221  /* Determine added ASN length */
222  asn_len = p - sig;
223 
224  memcpy( p, hash, hashlen );
225  }
226 
227  if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
228  asn_len + hashlen, sig, &olen ) != CKR_OK )
229  {
231  }
232 
233  return( 0 );
234 }
235 
236 #endif /* defined(POLARSSL_PKCS11_C) */
#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE
The output buffer for decryption is not large enough.
Definition: rsa.h:49
static size_t pk_get_len(const pk_context *ctx)
Get the length in bytes of the underlying key.
Definition: pk.h:264
#define ASN1_NULL
Definition: asn1.h:75
Memory allocation layer.
#define ASN1_OID
Definition: asn1.h:76
void *(* polarssl_malloc)(size_t len)
int x509_crt_parse(x509_crt *chain, const unsigned char *buf, size_t buflen)
Parse one or more certificates and add them to the chained list.
#define ASN1_SEQUENCE
Definition: asn1.h:78
void x509_crt_free(x509_crt *crt)
Unallocate all certificate data.
#define ASN1_CONSTRUCTED
Definition: asn1.h:88
static unsigned char md_get_size(const md_info_t *md_info)
Returns the size of the message digest output.
Definition: md.h:205
Object Identifier (OID) database.
md_type_t
Definition: md.h:51
const md_info_t * md_info_from_type(md_type_t md_type)
Returns the message digest information associated with the given digest type.
Container for an X.509 certificate.
Definition: x509_crt.h:53
#define RSA_PRIVATE
Definition: rsa.h:56
void x509_crt_init(x509_crt *crt)
Initialize a certificate (chain)
void(* polarssl_free)(void *ptr)
X.509 certificate parsing and writing.
Generic message digest wrapper.
#define POLARSSL_ERR_RSA_BAD_INPUT_DATA
Bad input parameters to function.
Definition: rsa.h:42
int oid_get_oid_by_md(md_type_t md_alg, const char **oid, size_t *olen)
Translate md_type into hash algorithm OID.
pk_context pk
Container for the public key context.
Definition: x509_crt.h:71
#define ASN1_OCTET_STRING
Definition: asn1.h:74
Wrapper for PKCS#11 library libpkcs11-helper.
Message digest information.
Definition: md.h:73