1 /*
2  * Copyright (c) 2005-2018 Alon Bar-Lev <alon.barlev@gmail.com>
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, or the BSD license.
7  *
8  * GNU General Public License (GPL) Version 2
9  * ===========================================
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program (see the file COPYING.GPL included with this
21  * distribution); if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  *
24  * BSD License
25  * ============
26  * Redistribution and use in source and binary forms, with or without
27  * modification, are permitted provided that the following conditions are met:
28  *
29  *     o Redistributions of source code must retain the above copyright notice,
30  *       this list of conditions and the following disclaimer.
31  *     o Redistributions in binary form must reproduce the above copyright
32  *       notice, this list of conditions and the following disclaimer in the
33  *       documentation and/or other materials provided with the distribution.
34  *     o Neither the name of the Alon Bar-Lev nor the names of its
35  *       contributors may be used to endorse or promote products derived from
36  *       this software without specific prior written permission.
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
39  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
42  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
43  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
44  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
45  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
46  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
48  * POSSIBILITY OF SUCH DAMAGE.
49  */
50 
51 /**
52  * @addtogroup pkcs11h_certificate Certificate interface
53  *
54  * X.509 certificate interface, provides signature and decryption.
55  *
56  * @{
57  */
58 
59 /**
60  * @file pkcs11h-certificate.h
61  * @brief pkcs11-helper certificate functions.
62  * @author Alon Bar-Lev <alon.barlev@gmail.com>
63  * @see pkcs11h_certificate.
64  */
65 
66 /**
67  * @example test-certificate.c
68  *
69  * The following example shows some basic usage of the certificate interface.
70  */
71 
72 #ifndef __PKCS11H_CERTIFICATE_H
73 #define __PKCS11H_CERTIFICATE_H
74 
75 #include <pkcs11-helper-1.0/pkcs11h-core.h>
76 
77 #if defined(__cplusplus)
78 extern "C" {
79 #endif
80 
81 struct pkcs11h_certificate_id_s;
82 struct pkcs11h_certificate_s;
83 
84 /**
85  * @brief Certificate id reference.
86  */
87 typedef struct pkcs11h_certificate_id_s *pkcs11h_certificate_id_t;
88 
89 /**
90  * @brief Certificate object.
91  */
92 typedef struct pkcs11h_certificate_s *pkcs11h_certificate_t;
93 
94 struct pkcs11h_certificate_id_list_s;
95 
96 /**
97  * @brief Certificate id list.
98  */
99 typedef struct pkcs11h_certificate_id_list_s *pkcs11h_certificate_id_list_t;
100 
101 /**
102  * @brief Certificate id reference
103  */
104 struct pkcs11h_certificate_id_s {
105 	/** Token id */
106 	pkcs11h_token_id_t token_id;
107 
108 	/** displayName for users */
109 	char displayName[1024];
110 	/** CKA_ID of object */
111 	CK_BYTE_PTR attrCKA_ID;
112 	/** CKA_ID size */
113 	size_t attrCKA_ID_size;
114 
115 	/** Certificate blob (if available) */
116 	unsigned char *certificate_blob;
117 	/** Certificate blob size */
118 	size_t certificate_blob_size;
119 };
120 
121 /**
122  * @brief Certificate id list
123  */
124 struct pkcs11h_certificate_id_list_s {
125 	/** Next element */
126 	pkcs11h_certificate_id_list_t next;
127 	/** Certificate id */
128 	pkcs11h_certificate_id_t certificate_id;
129 };
130 
131 /**
132  * @brief Free certificate_id object.
133  * @param certificate_id	Certificate id.
134  * @return CK_RV.
135  */
136 CK_RV
137 pkcs11h_certificate_freeCertificateId (
138 	IN pkcs11h_certificate_id_t certificate_id
139 );
140 
141 /**
142  * @brief Duplicate certificate_id object.
143  * @param to	Target.
144  * @param from	Source.
145  * @return CK_RV.
146  * @note Caller must free result.
147  * @see pkcs11h_certificate_freeCertificateId().
148  */
149 CK_RV
150 pkcs11h_certificate_duplicateCertificateId (
151 	OUT pkcs11h_certificate_id_t * const to,
152 	IN const pkcs11h_certificate_id_t from
153 );
154 
155 /**
156  * @brief Sets internal certificate_id blob.
157  * @param certificate_id	Certificate id object.
158  * @param blob			Certificate blob.
159  * @param blob_size		Certificate blob size.
160  * @return CK_RV.
161  * @remarks
162  * Useful to set after deserialization so certificate is available and not read from token.
163  */
164 CK_RV
165 pkcs11h_certificate_setCertificateIdCertificateBlob (
166 	IN const pkcs11h_certificate_id_t certificate_id,
167 	IN const unsigned char * const blob,
168 	IN const size_t blob_size
169 );
170 
171 /**
172  * @brief Free certificate object.
173  * @param certificate	Certificate object.
174  * @return CK_RV.
175  */
176 CK_RV
177 pkcs11h_certificate_freeCertificate (
178 	IN pkcs11h_certificate_t certificate
179 );
180 
181 /**
182  * @brief Create a certificate object out of certificate_id.
183  * @param certificate_id	Certificate id object to be based on.
184  * @param user_data		Optional user data, to be passed to hooks.
185  * @param mask_prompt		Allow prompt @ref PKCS11H_PROMPT_MASK.
186  * @param pin_cache_period	Session specific cache period.
187  * @param p_certificate		Receives certificate object.
188  * @note Caller must free result.
189  * @see pkcs11h_certificate_freeCertificate().
190  * @remarks
191  * The certificate id object may not specify the certificate blob.
192  */
193 CK_RV
194 pkcs11h_certificate_create (
195 	IN const pkcs11h_certificate_id_t certificate_id,
196 	IN void * const user_data,
197 	IN const unsigned mask_prompt,
198 	IN const int pin_cache_period,
199 	OUT pkcs11h_certificate_t * const p_certificate
200 );
201 
202 /**
203  * @brief Extract user data out of certificate.
204  * @param certificate	Certificate object.
205  * @return Mask prompt @ref PKCS11H_PROMPT_MASK.
206  */
207 unsigned
208 pkcs11h_certificate_getPromptMask (
209 	IN const pkcs11h_certificate_t certificate
210 );
211 
212 /**
213  * @brief Extract user data out of certificate.
214  * @param certificate	Certificate object.
215  * @param mask_prompt	Allow prompt @ref PKCS11H_PROMPT_MASK.
216  */
217 void
218 pkcs11h_certificate_setPromptMask (
219 	IN const pkcs11h_certificate_t certificate,
220 	IN const unsigned mask_prompt
221 );
222 
223 /**
224  * @brief Extract user data out of certificate.
225  * @param certificate	Certificate object.
226  * @return User data.
227  */
228 void *
229 pkcs11h_certificate_getUserData (
230 	IN const pkcs11h_certificate_t certificate
231 );
232 
233 /**
234  * @brief Extract user data out of certificate.
235  * @param certificate	Certificate object.
236  * @param user_data	Optional user data, to be passed to hooks.
237  */
238 void
239 pkcs11h_certificate_setUserData (
240 	IN const pkcs11h_certificate_t certificate,
241 	IN void * const user_data
242 );
243 
244 /**
245  * @brief Get certifiate id object out of a certifiate.
246  * @param certificate		Certificate object.
247  * @param p_certificate_id	Certificate id object pointer.
248  * @return CK_RV.
249  * @note Caller must free result.
250  * @see pkcs11h_certificate_freeCertificateId().
251  */
252 CK_RV
253 pkcs11h_certificate_getCertificateId (
254 	IN const pkcs11h_certificate_t certificate,
255 	OUT pkcs11h_certificate_id_t * const p_certificate_id
256 );
257 
258 /**
259  * @brief Get the certificate blob out of the certificate object.
260  * @param certificate			Certificate object.
261  * @param certificate_blob		Buffer.
262  * @param p_certificate_blob_size	Buffer size.
263  * @return CK_RV.
264  * @note certificate_blob may be NULL in order to get size.
265  */
266 CK_RV
267 pkcs11h_certificate_getCertificateBlob (
268 	IN const pkcs11h_certificate_t certificate,
269 	OUT unsigned char * const certificate_blob,
270 	IN OUT size_t * const p_certificate_blob_size
271 );
272 
273 /**
274  * @brief Serialize certificate_id into a string
275  * @param sz			Output string.
276  * @param max			Max buffer size.
277  * @param certificate_id	id to serialize
278  * @return CK_RV.
279  * @note sz may be NULL in order to get size.
280  */
281 CK_RV
282 pkcs11h_certificate_serializeCertificateId (
283 	OUT char * const sz,
284 	IN OUT size_t *max,
285 	IN const pkcs11h_certificate_id_t certificate_id
286 );
287 
288 /**
289  * @brief Deserialize certificate_id out of string.
290  * @param p_certificate_id	id.
291  * @param sz			Inut string
292  * @return CK_RV.
293  * @note Caller must free result.
294  * @see pkcs11h_certificate_freeCertificateId().
295  */
296 CK_RV
297 pkcs11h_certificate_deserializeCertificateId (
298 	OUT pkcs11h_certificate_id_t * const p_certificate_id,
299 	IN const char * const sz
300 );
301 
302 /**
303  * @brief Ensure certificate is accessible.
304  * @param certificate		Certificate object.
305  * @return CK_RV.
306  */
307 CK_RV
308 pkcs11h_certificate_ensureCertificateAccess (
309 	IN const pkcs11h_certificate_t certificate
310 );
311 
312 /**
313  * @brief Ensure key is accessible.
314  * @param certificate		Certificate object.
315  * @return CK_RV.
316  */
317 CK_RV
318 pkcs11h_certificate_ensureKeyAccess (
319 	IN const pkcs11h_certificate_t certificate
320 );
321 
322 /**
323  * @brief Lock session for threded environment.
324  * @param certificate		Certificate object.
325  * @return CK_RV.
326  * @remarks
327  * This must be called on threaded environment, so both calls to _sign and
328  * _signRecover and _decrypt will be from the same source.
329  * Failing to lock session, will result with CKR_OPERATION_ACTIVE if
330  * provider is good, or unexpected behaviour for others.
331  * @remarks
332  * It is save to call this also in none threaded environment, it will do nothing.
333  * Call this also if you are doing one stage operation, since locking is not
334  * done by method.
335  */
336 CK_RV
337 pkcs11h_certificate_lockSession (
338 	IN const pkcs11h_certificate_t certificate
339 );
340 
341 /**
342  * @brief Releases session lock.
343  * @param certificate		Certificate object.
344  * @return CK_RV.
345  * @see pkcs11h_certificate_lockSession().
346  */
347 CK_RV
348 pkcs11h_certificate_releaseSession (
349 	IN const pkcs11h_certificate_t certificate
350 );
351 
352 /**
353  * @brief Sign data.
354  * @param certificate		Certificate object.
355  * @param mech_type		PKCS#11 mechanism.
356  * @param source		Buffer to sign.
357  * @param source_size		Buffer size.
358  * @param target		Target buffer.
359  * @param p_target_size		Target buffer size.
360  * @return CK_RV.
361  * @note target may be NULL to get size.
362  * @attention When using in threaded environment session must be locked.
363  * @see pkcs11h_certificate_lockSession().
364  * @see pkcs11h_certificate_signAny().
365  */
366 CK_RV
367 pkcs11h_certificate_sign (
368 	IN const pkcs11h_certificate_t certificate,
369 	IN const CK_MECHANISM_TYPE mech_type,
370 	IN const unsigned char * const source,
371 	IN const size_t source_size,
372 	OUT unsigned char * const target,
373 	IN OUT size_t * const p_target_size
374 );
375 
376 /**
377  * @brief Sign data.
378  * @param certificate		Certificate object.
379  * @param mech_type		PKCS#11 mechanism.
380  * @param source		Buffer to sign.
381  * @param source_size		Buffer size.
382  * @param target		Target buffer.
383  * @param p_target_size		Target buffer size.
384  * @return CK_RV.
385  * @note target may be NULL to get size.
386  * @attention When using in threaded environment session must be locked.
387  * @see pkcs11h_certificate_lockSession().
388  * @see pkcs11h_certificate_signAny().
389  */
390 CK_RV
391 pkcs11h_certificate_signRecover (
392 	IN const pkcs11h_certificate_t certificate,
393 	IN const CK_MECHANISM_TYPE mech_type,
394 	IN const unsigned char * const source,
395 	IN const size_t source_size,
396 	OUT unsigned char * const target,
397 	IN OUT size_t * const p_target_size
398 );
399 
400 /**
401  * @brief Decrypt data.
402  * @param certificate		Certificate object.
403  * @param mech_type		PKCS#11 mechanism.
404  * @param source		Buffer to sign.
405  * @param source_size		Buffer size.
406  * @param target		Target buffer.
407  * @param p_target_size		Target buffer size.
408  * @return CK_RV.
409  * @note target may be NULL to get size.
410  * @attention When using in threaded environment session must be locked.
411  * @see pkcs11h_certificate_lockSession().
412  */
413 CK_RV
414 pkcs11h_certificate_decrypt (
415 	IN const pkcs11h_certificate_t certificate,
416 	IN const CK_MECHANISM_TYPE mech_type,
417 	IN const unsigned char * const source,
418 	IN const size_t source_size,
419 	OUT unsigned char * const target,
420 	IN OUT size_t * const p_target_size
421 );
422 
423 /**
424  * @brief Decrypt data.
425  * @param certificate		Certificate object.
426  * @param mech_type		PKCS#11 mechanism.
427  * @param source		Buffer to sign.
428  * @param source_size		Buffer size.
429  * @param target		Target buffer.
430  * @param p_target_size		Target buffer size.
431  * @return CK_RV.
432  * @note target may be NULL to get size.
433  * @attention When using in threaded environment session must be locked.
434  * @see pkcs11h_certificate_lockSession().
435  */
436 CK_RV
437 pkcs11h_certificate_unwrap (
438 	IN const pkcs11h_certificate_t certificate,
439 	IN const CK_MECHANISM_TYPE mech_type,
440 	IN const unsigned char * const source,
441 	IN const size_t source_size,
442 	OUT unsigned char * const target,
443 	IN OUT size_t * const p_target_size
444 );
445 
446 /**
447  * @brief Sign data mechanism determined by key attributes.
448  * @param certificate		Certificate object.
449  * @param mech_type		PKCS#11 mechanism.
450  * @param source		Buffer to sign.
451  * @param source_size		Buffer size.
452  * @param target		Target buffer.
453  * @param p_target_size		Target buffer size.
454  * @return CK_RV.
455  * @note target may be NULL to get size.
456  * @attention When using in threaded environment session must be locked.
457  * @see pkcs11h_certificate_lockSession().
458  */
459 CK_RV
460 pkcs11h_certificate_signAny (
461 	IN const pkcs11h_certificate_t certificate,
462 	IN const CK_MECHANISM_TYPE mech_type,
463 	IN const unsigned char * const source,
464 	IN const size_t source_size,
465 	OUT unsigned char * const target,
466 	IN OUT size_t * const p_target_size
467 );
468 
469 /**
470  * @brief Decrypt data mechanism determined by key attributes.
471  * @param certificate		Certificate object.
472  * @param mech_type		PKCS#11 mechanism.
473  * @param source		Buffer to sign.
474  * @param source_size		Buffer size.
475  * @param target		Target buffer.
476  * @param p_target_size		Target buffer size.
477  * @return CK_RV.
478  * @note target may be NULL to get size.
479  * @attention When using in threaded environment session must be locked.
480  * @see pkcs11h_certificate_lockSession().
481  */
482 CK_RV
483 pkcs11h_certificate_decryptAny (
484 	IN const pkcs11h_certificate_t certificate,
485 	IN const CK_MECHANISM_TYPE mech_type,
486 	IN const unsigned char * const source,
487 	IN const size_t source_size,
488 	OUT unsigned char * const target,
489 	IN OUT size_t * const p_target_size
490 );
491 
492 /**
493  * @brief Free certificate_id list.
494  * @param cert_id_list		List.
495  * @return CK_RV.
496  */
497 CK_RV
498 pkcs11h_certificate_freeCertificateIdList (
499 	IN const pkcs11h_certificate_id_list_t cert_id_list
500 );
501 
502 /**
503  * @brief Enumerate available certificates on specific token
504  * @param token_id			Token id to enum.
505  * @param method			How to fetch certificates @ref PKCS11H_ENUM_METHOD.
506  * @param user_data			Some user specific data.
507  * @param mask_prompt			Allow prompt @ref PKCS11H_PROMPT_MASK.
508  * @param p_cert_id_issuers_list	Receives issues list.
509  * @param p_cert_id_end_list		Receives end certificates list.
510  * @return CK_RV.
511  * @note p_cert_id_issuers_list may be NULL.
512  * @note Caller must free result.
513  * @note This function will likely take long time.
514  * @see pkcs11h_certificate_freeCertificateIdList().
515  */
516 CK_RV
517 pkcs11h_certificate_enumTokenCertificateIds (
518 	IN const pkcs11h_token_id_t token_id,
519 	IN const unsigned method,
520 	IN void * const user_data,
521 	IN const unsigned mask_prompt,
522 	OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
523 	OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
524 );
525 
526 /**
527  * @brief Enumerate available certificates.
528  * @param method			How to fetch certificates @ref PKCS11H_ENUM_METHOD.
529  * @param user_data			Some user specific data.
530  * @param mask_prompt			Allow prompt @ref PKCS11H_PROMPT_MASK.
531  * @param p_cert_id_issuers_list	Receives issues list.
532  * @param p_cert_id_end_list		Receives end certificates list.
533  * @note p_cert_id_issuers_list may be NULL.
534  * @note Caller must free result.
535  * @note This function will likely take long time.
536  * @see pkcs11h_certificate_freeCertificateIdList().
537  */
538 CK_RV
539 pkcs11h_certificate_enumCertificateIds (
540 	IN const unsigned method,
541 	IN void * const user_data,
542 	IN const unsigned mask_prompt,
543 	OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
544 	OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
545 );
546 
547 #ifdef __cplusplus
548 }
549 #endif
550 
551 /** @} */
552 
553 #endif				/* __PKCS11H_CERTIFICATE_H */
554