PolarSSL v1.3.8
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_PLATFORM_C)
38 #include "polarssl/platform.h"
39 #else
40 #include <stdlib.h>
41 #define polarssl_malloc malloc
42 #define polarssl_free free
43 #endif
44 
45 int pkcs11_x509_cert_init( x509_crt *cert, pkcs11h_certificate_t pkcs11_cert )
46 {
47  int ret = 1;
48  unsigned char *cert_blob = NULL;
49  size_t cert_blob_size = 0;
50 
51  if( cert == NULL )
52  {
53  ret = 2;
54  goto cleanup;
55  }
56 
57  if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL,
58  &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,
72  &cert_blob_size ) != CKR_OK )
73  {
74  ret = 5;
75  goto cleanup;
76  }
77 
78  if( 0 != x509_crt_parse( cert, cert_blob, cert_blob_size ) )
79  {
80  ret = 6;
81  goto cleanup;
82  }
83 
84  ret = 0;
85 
86 cleanup:
87  if( NULL != cert_blob )
88  polarssl_free( cert_blob );
89 
90  return( ret );
91 }
92 
93 
94 int pkcs11_priv_key_init( pkcs11_context *priv_key,
95  pkcs11h_certificate_t pkcs11_cert )
96 {
97  int ret = 1;
98  x509_crt cert;
99 
100  x509_crt_init( &cert );
101 
102  if( priv_key == NULL )
103  goto cleanup;
104 
105  if( 0 != pkcs11_x509_cert_init( &cert, pkcs11_cert ) )
106  goto cleanup;
107 
108  priv_key->len = pk_get_len( &cert.pk );
109  priv_key->pkcs11h_cert = pkcs11_cert;
110 
111  ret = 0;
112 
113 cleanup:
114  x509_crt_free( &cert );
115 
116  return( ret );
117 }
118 
119 void pkcs11_priv_key_free( pkcs11_context *priv_key )
120 {
121  if( NULL != priv_key )
122  pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
123 }
124 
125 int pkcs11_decrypt( pkcs11_context *ctx,
126  int mode, size_t *olen,
127  const unsigned char *input,
128  unsigned char *output,
129  size_t output_max_len )
130 {
131  size_t input_len, output_len;
132 
133  if( NULL == ctx )
135 
136  if( RSA_PRIVATE != mode )
138 
139  output_len = input_len = ctx->len;
140 
141  if( input_len < 16 || input_len > output_max_len )
143 
144  /* Determine size of output buffer */
145  if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
146  input_len, NULL, &output_len ) != CKR_OK )
147  {
149  }
150 
151  if( output_len > output_max_len )
153 
154  if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
155  input_len, output, &output_len ) != CKR_OK )
156  {
158  }
159  *olen = output_len;
160  return( 0 );
161 }
162 
163 int pkcs11_sign( pkcs11_context *ctx,
164  int mode,
165  md_type_t md_alg,
166  unsigned int hashlen,
167  const unsigned char *hash,
168  unsigned char *sig )
169 {
170  size_t sig_len = 0, asn_len = 0, oid_size = 0;
171  unsigned char *p = sig;
172  const char *oid;
173 
174  if( NULL == ctx )
176 
177  if( RSA_PRIVATE != mode )
179 
180  if( md_alg != POLARSSL_MD_NONE )
181  {
182  const md_info_t *md_info = md_info_from_type( md_alg );
183  if( md_info == NULL )
185 
186  if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
188 
189  hashlen = md_get_size( md_info );
190  asn_len = 10 + oid_size;
191  }
192 
193  sig_len = ctx->len;
194  if( hashlen > sig_len || asn_len > sig_len ||
195  hashlen + asn_len > sig_len )
196  {
198  }
199 
200  if( md_alg != POLARSSL_MD_NONE )
201  {
202  /*
203  * DigestInfo ::= SEQUENCE {
204  * digestAlgorithm DigestAlgorithmIdentifier,
205  * digest Digest }
206  *
207  * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
208  *
209  * Digest ::= OCTET STRING
210  */
212  *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
214  *p++ = (unsigned char) ( 0x04 + oid_size );
215  *p++ = ASN1_OID;
216  *p++ = oid_size & 0xFF;
217  memcpy( p, oid, oid_size );
218  p += oid_size;
219  *p++ = ASN1_NULL;
220  *p++ = 0x00;
221  *p++ = ASN1_OCTET_STRING;
222  *p++ = hashlen;
223  }
224 
225  memcpy( p, hash, hashlen );
226 
227  if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
228  asn_len + hashlen, sig, &sig_len ) != CKR_OK )
229  {
231  }
232 
233  return( 0 );
234 }
235 
236 #endif /* defined(POLARSSL_PKCS11_C) */