1 /****************************************************************************
2 *																			*
3 *						PKCS #15 Definitions Header File					*
4 *						Copyright Peter Gutmann 1996-2014					*
5 *																			*
6 ****************************************************************************/
7 
8 #ifndef _PKCS15_DEFINED
9 
10 #define _PKCS15_DEFINED
11 
12 /* The format used to protect the private key components is a standard
13    cryptlib envelope, however for various reasons the required enveloping
14    functionality (which in practice is just minimal code to process a
15    PasswordRecipientInfo at the start of the data) is duplicated here
16    because:
17 
18 	1. It's somewhat inelegant to use the heavyweight enveloping routines to
19 	   wrap up 100 bytes of data.
20 
21 	2. The enveloping code is enormous and complex, especially when extra
22 	   sections like zlib and PGP and S/MIME support are factored in.  This
23 	   makes it difficult to compile a stripped-down version of cryptlib,
24 	   since private key storage will require all of the enveloping code to
25 	   be included.
26 
27 	3. Since the enveloping code is general-purpose, it doesn't allow very
28 	   precise control over the data being processed.  Specifically, it's
29 	   necessary to write the private key components to a buffer in plaintext
30 	   form, which isn't permitted by the cryptlib kernel.
31 
32    For these reasons the PKCS #15 modules include the code to process minimal
33    (password-encrypted data) envelopes */
34 
35 /* Alongside per-key protection, PKCS #15 also allows for an entire keyset
36    to be integrity-protected, but the key management makes this more or less
37    impossible to deploy using a general-purpose API.  If only a single key
38    is present in the file then it's partly feasible, except that once a
39    keyset is cast in stone no further updates can be made without requiring
40    passwords at odd times.  For example a certificate update would require a
41    (private-key) password in order to recalculate the integrity-check value
42    once the certificate has been added.  In addition the password would need
43    to be supplied at file open, when the whole file is parsed, and then
44    again when the private key is read, which leads to a rather puzzling API
45    for anyone not in the know.
46 
47    In the presence of multiple keys this becomes even more awkward since the
48    per-key password isn't necessarily the same as the per-file password, so
49    you'd need to provide a password to open the file and then possibly
50    another one to get the key, unless it was the same as the per-file
51    password.  If there was one per-file password and multiple per-key
52    passwords then you would't know which key or keys used the per-file
53    password unless you opportunistically tried on each per-key access, and
54    the chances of that successfully making it up into any UI that people
55    create seem slim.  In addition updates are even more problematic than for
56    the one file, one key case because whoever last added a key would end up
57    with their per-key password authenticating the whole file */
58 
59 /****************************************************************************
60 *																			*
61 *								PKCS #15 Constants							*
62 *																			*
63 ****************************************************************************/
64 
65 /* Each PKCS #15 keyset can contain information for multiple personalities
66    (although it's extremely unlikely to contain more than one or two), we
67    allow a maximum of MAX_PKCS15_OBJECTS per keyset in order to discourage
68    them from being used as general-purpose public-key keysets, which they're
69    not supposed to be.  A setting of 16 objects consumes ~2K of memory
70    (16 x ~128) and seems like a sensible upper bound so we choose that as
71    the limit */
72 
73 #ifdef CONFIG_CONSERVE_MEMORY
74   #define MAX_PKCS15_OBJECTS	8
75 #else
76   #define MAX_PKCS15_OBJECTS	16
77 #endif /* CONFIG_CONSERVE_MEMORY */
78 
79 /* Usually a PKCS #15 personality consists of a collection of related PKCS
80    #15 objects (typically a public and private key and a certificate), but
81    sometimes we have personalities that consist only of a certificate and
82    little other information (for example a trusted CA root certificate,
83    which contains no user-supplied information such as a label).  In
84    addition there's an unrecognised data-type for which we interpret the
85    metadata but can't perform any other operations with */
86 
87 typedef enum {
88 	PKCS15_SUBTYPE_NONE,			/* Non-personality */
89 	PKCS15_SUBTYPE_NORMAL,			/* Standard personality, keys+optional cert */
90 	PKCS15_SUBTYPE_CERT,			/* Standalone certificate */
91 	PKCS15_SUBTYPE_SECRETKEY,		/* Secret key */
92 	PKCS15_SUBTYPE_DATA,			/* Pre-encoded cryptlib-specific data */
93 	PKCS15_SUBTYPE_UNRECOGNISED,	/* Unrecognised data type */
94 	PKCS15_SUBTYPE_LAST
95 	} PKCS15_SUBTYPE;
96 
97 /* The types of object that we can find in a PKCS #15 file */
98 
99 typedef enum { PKCS15_OBJECT_NONE, PKCS15_OBJECT_PUBKEY,
100 			   PKCS15_OBJECT_PRIVKEY, PKCS15_OBJECT_CERT,
101 			   PKCS15_OBJECT_SECRETKEY, PKCS15_OBJECT_DATA,
102 			   PKCS15_OBJECT_UNRECOGNISED, PKCS15_OBJECT_LAST
103 			   } PKCS15_OBJECT_TYPE;
104 
105 /* The types of key identifiers that we can find attached to an object */
106 
107 enum { PKCS15_KEYID_NONE, PKCS15_KEYID_ISSUERANDSERIALNUMBER,
108 	   PKCS15_KEYID_SUBJECTKEYIDENTIFIER, PKCS15_KEYID_ISSUERANDSERIALNUMBERHASH,
109 	   PKCS15_KEYID_SUBJECTKEYHASH, PKCS15_KEYID_ISSUERKEYHASH,
110 	   PKCS15_KEYID_ISSUERNAMEHASH, PKCS15_KEYID_SUBJECTNAMEHASH,
111 	   PKCS15_KEYID_PGP2, PKCS15_KEYID_OPENPGP, PKCS15_KEYID_LAST };
112 
113 /* PKCS #15 key usage flags, a complex mixture of PKCS #11 and some bits of
114    X.509 */
115 
116 #define PKCS15_USAGE_ENCRYPT		0x0001
117 #define PKCS15_USAGE_DECRYPT		0x0002
118 #define PKCS15_USAGE_SIGN			0x0004
119 #define PKCS15_USAGE_SIGNRECOVER	0x0008
120 #define PKCS15_USAGE_WRAP			0x0010
121 #define PKCS15_USAGE_UNWRAP			0x0020
122 #define PKCS15_USAGE_VERIFY			0x0040
123 #define PKCS15_USAGE_VERIFYRECOVER	0x0080
124 #define PKCS15_USAGE_DERIVE			0x0100
125 #define PKCS15_USAGE_NONREPUDIATION	0x0200
126 
127 /* Symbolic values for range checking of the usage flags */
128 
129 #define PKSC15_USAGE_FLAG_NONE		0x0000
130 #define PKCS15_USAGE_FLAG_MAX		0x03FF
131 
132 /* PKCS #15 flags that can't be set for public keys.  We use this as a mask
133    to derive public-key flags from private key ones */
134 
135 #define PUBKEY_USAGE_MASK	~( PKCS15_USAGE_DECRYPT | PKCS15_USAGE_SIGN | \
136 							   PKCS15_USAGE_SIGNRECOVER | PKCS15_USAGE_UNWRAP )
137 
138 /* PKCS #15 usage types for encryption and signature keys.  We use these when
139    looking specifically for signing or encryption keys */
140 
141 #define ENCR_USAGE_MASK		( PKCS15_USAGE_ENCRYPT | PKCS15_USAGE_DECRYPT | \
142 							  PKCS15_USAGE_WRAP | PKCS15_USAGE_UNWRAP )
143 #define SIGN_USAGE_MASK		( PKCS15_USAGE_SIGN | PKCS15_USAGE_SIGNRECOVER | \
144 							  PKCS15_USAGE_VERIFY | PKCS15_USAGE_VERIFYRECOVER | \
145 							  PKCS15_USAGE_NONREPUDIATION )
146 
147 /* The access flags for various types of key objects.  For a public key we
148    set 'extractable', for a private key we set 'sensitive',
149    'alwaysSensitive', and 'neverExtractable' */
150 
151 #define KEYATTR_ACCESS_PUBLIC	0x02	/* 00010b */
152 #define KEYATTR_ACCESS_PRIVATE	0x0D	/* 01101b */
153 
154 /* When adding a public key and/or certificate to a PKCS #15 collection we
155    have to be able to cleanly handle the addition of arbitrary collections of
156    potentially overlapping objects.  Since a public key is a subset of the
157    data in a certificate, if we're adding a certificate + public key pair
158    the certificate data overrides the public key, which isn't added at all.
159    This leads to some rather convoluted logic for deciding what needs
160    updating and under which conditions.  The actions taken are:
161 
162 	key only:	if present
163 					return( CRYPT_ERROR_DUPLICATE )
164 				else
165 					add key;
166 	cert only:	if present
167 					return( CRYPT_ERROR_DUPLICATE );
168 				elif( matching key present )
169 					add, delete key data;
170 				elif( trusted certificate )
171 					add as trusted certificate;
172 				else
173 					error;
174 	key+cert:	if key present and certificate present
175 					return( CRYPT_ERROR_DUPLICATE );
176 				delete key;
177 				if certificate present -> don't add certificate;
178 
179    The following values specify the action to be taken when adding a
180    certificate */
181 
182 typedef enum {
183 	CERTADD_NONE,			/* No certificate add action */
184 	CERTADD_UPDATE_EXISTING,/* Update existing key info with a certificate */
185 	CERTADD_NORMAL,			/* Add a certificate for which no key info present */
186 	CERTADD_STANDALONE_CERT,/* Add a standalone certificate not assoc'd with a key */
187 	CERTADD_LAST			/* Last valid certificate add action */
188 	} CERTADD_TYPE;
189 
190 /* Since PKCS #15 uses more key ID types than are used by the rest of
191    cryptlib, we extend the standard range with PKCS15-only types */
192 
193 #define CRYPT_KEYIDEX_ID				CRYPT_KEYID_NONE
194 
195 /* The minimum size of an object in a keyset, used for sanity-checking when
196    reading a keyset */
197 
198 #define MIN_OBJECT_SIZE		16
199 
200 /* When writing attributes it's useful to have a fixed-size buffer rather
201    than having to mess around with all sorts of variable-length structures,
202    the following value defines the maximum size of the attribute data that
203    we can write (that is, the I/O stream is opened with this size and
204    generates a CRYPT_ERROR_OVERFLOW if we go beyond this).  The maximum-
205    length buffer contents are two CRYPT_MAX_TEXTSIZE strings, about half a
206    dozen hashes (as IDs for subject, issuer, and so on), and a few odd bits
207    and pieces so this is plenty */
208 
209 #define KEYATTR_BUFFER_SIZE	512
210 
211 /****************************************************************************
212 *																			*
213 *							PKCS #15 Types and Structures					*
214 *																			*
215 ****************************************************************************/
216 
217 /* The following structure contains the the information for one personality,
218    which covers one or more of a private key, public key, and certificate */
219 
220 typedef struct {
221 	/* General information on the personality: The subtype, a local unique
222 	   identifier which is easier to manage than the iD (this is used when
223 	   enumerating PKCS #15 items in a keyset, the last-read-item entry is
224 	   set to the index value), the PKCS #15 object label, and the PKCS #15
225 	   object ID and key ID (which is usually the same as the object ID) */
226 	PKCS15_SUBTYPE type;			/* Personality subtype */
227 	int index;						/* Unique value for this personality */
228 	BUFFER( CRYPT_MAX_TEXTSIZE, labelLength ) \
229 	char label[ CRYPT_MAX_TEXTSIZE + 8 ];/* PKCS #15 object label */
230 	int labelLength;
231 	BUFFER( CRYPT_MAX_HASHSIZE, iDlength ) \
232 	BYTE iD[ CRYPT_MAX_HASHSIZE + 8 ];
233 	BUFFER( CRYPT_MAX_HASHSIZE, keyIDlength ) \
234 	BYTE keyID[ CRYPT_MAX_HASHSIZE + 8 ];
235 	int iDlength, keyIDlength;		/* PKCS #15 object ID and key ID */
236 
237 	/* Certificate-related ID information: Hash of the issuer name, subject
238 	   name, and issuerAndSerialNumber, and PGP key IDs */
239 	BUFFER( KEYID_SIZE, iAndSIDlength ) \
240 	BYTE iAndSID[ KEYID_SIZE + 8 ];
241 	BUFFER( KEYID_SIZE, subjectNameIDlength ) \
242 	BYTE subjectNameID[ KEYID_SIZE + 8 ];
243 	BUFFER( KEYID_SIZE, issuerNameIDlength ) \
244 	BYTE issuerNameID[ KEYID_SIZE + 8 ];
245 	BUFFER( KEYID_SIZE, pgp2KeyIDlength ) \
246 	BYTE pgp2KeyID[ PGP_KEYID_SIZE + 8 ];
247 	BUFFER( KEYID_SIZE, openPGPKeyIDlength ) \
248 	BYTE openPGPKeyID[ PGP_KEYID_SIZE + 8 ];
249 	int iAndSIDlength, subjectNameIDlength, issuerNameIDlength;
250 	int pgp2KeyIDlength, openPGPKeyIDlength;
251 
252 	/* Key/certificate object data */
253 	BUFFER_OPT_FIXED( pubKeyDataSize ) \
254 	void *pubKeyData;
255 	BUFFER_OPT_FIXED( privKeyDataSize ) \
256 	void *privKeyData;
257 	BUFFER_OPT_FIXED( certDataSize ) \
258 	void *certData;					/* Encoded object data */
259 	int pubKeyDataSize, privKeyDataSize, certDataSize;
260 	int pubKeyOffset, privKeyOffset, certOffset;
261 									/* Offset of payload in data */
262 	int pubKeyUsage, privKeyUsage;	/* Permitted usage for the key */
263 	int trustedUsage;				/* Usage which key is trusted for */
264 	BOOLEAN implicitTrust;			/* Whether certificate is implicitly trusted */
265 	time_t validFrom, validTo;		/* Key/certificate validity information */
266 
267 	/* Secret-key object data */
268 	BUFFER_OPT_FIXED( secretKeyDataSize ) \
269 	void *secretKeyData;			/* Encoded object data */
270 	int secretKeyDataSize, secretKeyOffset;
271 
272 	/* Data object data */
273 	CRYPT_ATTRIBUTE_TYPE dataType;	/* Type of the encoded object data */
274 	BUFFER_OPT_FIXED( dataDataSize ) \
275 	void *dataData;					/* Encoded object data */
276 	int dataDataSize, dataOffset;
277 	} PKCS15_INFO;
278 
279 /****************************************************************************
280 *																			*
281 *								PKCS #15 ASN.1 Tags							*
282 *																			*
283 ****************************************************************************/
284 
285 /* Context-specific tags for object types */
286 
287 enum { CTAG_PO_PRIVKEY, CTAG_PO_PUBKEY, CTAG_PO_TRUSTEDPUBKEY,
288 	   CTAG_PO_SECRETKEY, CTAG_PO_CERT, CTAG_PO_TRUSTEDCERT,
289 	   CTAG_PO_USEFULCERT, CTAG_PO_DATA, CTAG_PO_AUTH, CTAG_PO_LAST };
290 
291 /* Context-specific tags for the PublicKeyInfo record */
292 
293 enum { CTAG_PK_CERTIFICATE, CTAG_PK_CERTCHAIN, CTAG_PK_LAST };
294 
295 /* Context-specific tags for the object record */
296 
297 enum { CTAG_OB_SUBCLASSATTR, CTAG_OB_TYPEATTR, CTAG_OB_LAST };
298 
299 /* Context-specific tags for the object value record */
300 
301 enum { CTAG_OV_DIRECT, CTAG_OV_DUMMY, CTAG_OV_DIRECTPROTECTED,
302 	   CTAG_OV_DUMMY_DIRECTPROTECTED_EXT, CTAG_OV_DIRECTPROTECTED_EXT,
303 	   CTAG_OV_LAST };
304 
305 /* Context-specific tags for the class attributes record */
306 
307 enum { CTAG_KA_VALIDTO, CTAG_KA_LAST };
308 enum { CTAG_CA_DUMMY, CTAG_CA_TRUSTED_USAGE, CTAG_CA_IDENTIFIERS,
309 	   CTAG_CA_TRUSTED_IMPLICIT, CTAG_CA_VALIDTO, CTAG_CA_LAST };
310 enum { CTAG_PK_IDENTIFIERS };
311 
312 /* Context-specific tags for the public/private key objects record */
313 
314 enum { CTAG_PK_ECC, CTAG_PK_DH, CTAG_PK_DSA, CTAG_PK_KEA };
315 
316 /* Context-specific tags for the data objects record */
317 
318 enum { CTAG_DO_EXTERNALDO, CTAG_DO_OIDDO, CTAG_DO_LAST };
319 
320 /****************************************************************************
321 *																			*
322 *								PKCS #15 Functions							*
323 *																			*
324 ****************************************************************************/
325 
326 /* Utility functions in pkcs15.c */
327 
328 CHECK_RETVAL STDC_NONNULL_ARG( ( 3, 5 ) ) \
329 int getCertID( IN_HANDLE const CRYPT_HANDLE iCryptHandle,
330 			   IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE nameType,
331 			   OUT_BUFFER( nameIdMaxLen, *nameIdLen ) BYTE *nameID,
332 			   IN_LENGTH_SHORT_MIN( KEYID_SIZE ) const int nameIdMaxLen,
333 			   OUT_LENGTH_BOUNDED_Z( nameIdMaxLen ) int *nameIdLen );
334 CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 1 ) ) \
335 PKCS15_INFO *findEntry( IN_ARRAY( noPkcs15objects ) const PKCS15_INFO *pkcs15info,
336 						IN_LENGTH_SHORT const int noPkcs15objects,
337 						IN_KEYID_OPT const CRYPT_KEYID_TYPE keyIDtype,
338 							/* CRYPT_KEYIDEX_ID maps to CRYPT_KEYID_NONE */
339 						IN_BUFFER_OPT( keyIDlength ) const void *keyID,
340 						IN_LENGTH_KEYID_Z const int keyIDlength,
341 						IN_FLAGS_Z( KEYMGMT ) const int requestedUsage,
342 						const BOOLEAN isWildcardMatch );
343 CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 1 ) ) \
344 PKCS15_INFO *findFreeEntry( IN_ARRAY( noPkcs15objects ) \
345 								const PKCS15_INFO *pkcs15info,
346 							IN_LENGTH_SHORT const int noPkcs15objects,
347 							OUT_OPT_INDEX( noPkcs15objects ) int *index );
348 STDC_NONNULL_ARG( ( 1 ) ) \
349 void pkcs15freeEntry( INOUT PKCS15_INFO *pkcs15info );
350 STDC_NONNULL_ARG( ( 1 ) ) \
351 void pkcs15Free( INOUT_ARRAY( noPkcs15objects ) PKCS15_INFO *pkcs15info,
352 				 IN_RANGE( 1, MAX_PKCS15_OBJECTS ) const int noPkcs15objects );
353 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
354 int getValidityInfo( INOUT PKCS15_INFO *pkcs15info,
355 					 IN_HANDLE const CRYPT_HANDLE cryptHandle );
356 
357 /* Prototypes for functions in pkcs15_add.c */
358 
359 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
360 int getKeyTypeTag( IN_HANDLE_OPT const CRYPT_CONTEXT cryptContext,
361 				   IN_ALGO_OPT const CRYPT_ALGO_TYPE cryptAlgo,
362 				   OUT int *tag );
363 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
364 int addConfigData( IN_ARRAY( noPkcs15objects ) PKCS15_INFO *pkcs15info,
365 				   IN_LENGTH_SHORT const int noPkcs15objects,
366 				   IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE dataType,
367 				   IN_BUFFER( dataLength ) const char *data,
368 				   IN_LENGTH_SHORT const int dataLength );
369 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
370 int addSecretKey( IN_ARRAY( noPkcs15objects ) PKCS15_INFO *pkcs15info,
371 				  IN_LENGTH_SHORT const int noPkcs15objects,
372 				  IN_HANDLE const CRYPT_HANDLE iCryptContext );
373 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 11 ) ) \
374 int pkcs15AddKey( INOUT PKCS15_INFO *pkcs15infoPtr,
375 				  IN_HANDLE const CRYPT_HANDLE iCryptHandle,
376 				  IN_BUFFER_OPT( passwordLength ) const void *password,
377 				  IN_LENGTH_NAME_Z const int passwordLength,
378 				  IN_HANDLE const CRYPT_USER iOwnerHandle,
379 				  const BOOLEAN privkeyPresent, const BOOLEAN certPresent,
380 				  const BOOLEAN doAddCert, const BOOLEAN pkcs15keyPresent,
381 				  const BOOLEAN isStorageObject,
382 				  INOUT ERROR_INFO *errorInfo );
383 
384 /* Prototypes for functions in pkcs15_adpb.c */
385 
386 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 6 ) ) \
387 int pkcs15AddCert( INOUT PKCS15_INFO *pkcs15infoPtr,
388 				   IN_HANDLE const CRYPT_CERTIFICATE iCryptCert,
389 				   IN_BUFFER_OPT( privKeyAttributeSize ) \
390 					const void *privKeyAttributes,
391 				   IN_LENGTH_SHORT_Z const int privKeyAttributeSize,
392 				   IN_ENUM( CERTADD ) const CERTADD_TYPE certAddType,
393 				   INOUT ERROR_INFO *errorInfo );
394 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
395 int pkcs15AddCertChain( INOUT PKCS15_INFO *pkcs15info,
396 						IN_LENGTH_SHORT const int noPkcs15objects,
397 						IN_HANDLE const CRYPT_CERTIFICATE iCryptCert,
398 						INOUT ERROR_INFO *errorInfo );
399 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 8 ) ) \
400 int pkcs15AddPublicKey( INOUT PKCS15_INFO *pkcs15infoPtr,
401 						IN_HANDLE const CRYPT_HANDLE iCryptContext,
402 						IN_BUFFER( pubKeyAttributeSize ) \
403 							const void *pubKeyAttributes,
404 						IN_LENGTH_SHORT const int pubKeyAttributeSize,
405 						IN_ALGO const CRYPT_ALGO_TYPE pkcCryptAlgo,
406 						IN_LENGTH_PKC const int modulusSize,
407 						const BOOLEAN isStorageObject,
408 						INOUT ERROR_INFO *errorInfo );
409 
410 /* Prototypes for functions in pkcs15_adpr.c.  The private-key attribute
411    functions have to be accessible externally because adding or changing a
412    certificate for a private key can update the private-key attributes */
413 
414 STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
415 void updatePrivKeyAttributes( INOUT PKCS15_INFO *pkcs15infoPtr,
416 							  OUT_BUFFER_FIXED( newPrivKeyDataSize ) \
417 								void *newPrivKeyData,
418 							  IN_LENGTH_SHORT_MIN( 16 ) \
419 								const int newPrivKeyDataSize,
420 							  IN_BUFFER( privKeyAttributeSize ) \
421 								const void *privKeyAttributes,
422 							  IN_LENGTH_SHORT const int privKeyAttributeSize,
423 							  IN_LENGTH_SHORT const int privKeyInfoSize,
424 							  IN_TAG const int keyTypeTag );
425 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
426 int calculatePrivkeyStorage( OUT_BUFFER_ALLOC_OPT( *newPrivKeyDataSize ) \
427 								void **newPrivKeyDataPtr,
428 							 OUT_LENGTH_SHORT_Z int *newPrivKeyDataSize,
429 							 IN_BUFFER_OPT( origPrivKeyDataSize ) \
430 								const void *origPrivKeyData,
431 							 IN_LENGTH_SHORT_Z const int origPrivKeyDataSize,
432 							 IN_LENGTH_SHORT const int privKeySize,
433 							 IN_LENGTH_SHORT const int privKeyAttributeSize,
434 							 IN_LENGTH_SHORT_Z const int extraDataSize );
435 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 6, 11 ) ) \
436 int pkcs15AddPrivateKey( INOUT PKCS15_INFO *pkcs15infoPtr,
437 						 IN_HANDLE const CRYPT_HANDLE iPrivKeyContext,
438 						 IN_HANDLE const CRYPT_HANDLE iCryptOwner,
439 						 IN_BUFFER_OPT( passwordLength ) const char *password,
440 						 IN_LENGTH_NAME_Z const int passwordLength,
441 						 IN_BUFFER( privKeyAttributeSize ) \
442 							const void *privKeyAttributes,
443 						 IN_LENGTH_SHORT const int privKeyAttributeSize,
444 						 IN_ALGO const CRYPT_ALGO_TYPE pkcCryptAlgo,
445 						 IN_LENGTH_PKC const int modulusSize,
446 						 const BOOLEAN isStorageObject,
447 						 INOUT ERROR_INFO *errorInfo );
448 
449 /* Prototypes for functions in pkcs15_atrd.c/pkcs15_atwr.c */
450 
451 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4, 6, 7 ) ) \
452 int writeKeyAttributes( OUT_BUFFER( privKeyAttributeMaxLen, \
453 									*privKeyAttributeSize )
454 							void *privKeyAttributes,
455 						IN_LENGTH_SHORT_MIN( 16 ) \
456 							const int privKeyAttributeMaxLen,
457 						OUT_LENGTH_BOUNDED_Z( privKeyAttributeMaxLen ) \
458 							int *privKeyAttributeSize,
459 						OUT_BUFFER( pubKeyAttributeMaxLen, \
460 									*pubKeyAttributeSize ) \
461 							void *pubKeyAttributes,
462 						IN_LENGTH_SHORT_MIN( 16 ) \
463 							const int pubKeyAttributeMaxLen,
464 						OUT_LENGTH_BOUNDED_Z( pubKeyAttributeMaxLen ) \
465 							int *pubKeyAttributeSize,
466 						INOUT PKCS15_INFO *pkcs15infoPtr,
467 						IN_HANDLE const CRYPT_HANDLE iCryptContext,
468 						const BOOLEAN writeKeyIDs );
469 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
470 int writeCertAttributes( OUT_BUFFER( certAttributeMaxLen, *certAttributeSize ) \
471 							void *certAttributes,
472 						 IN_LENGTH_SHORT_MIN( 16 ) const int certAttributeMaxLen,
473 						 OUT_LENGTH_BOUNDED_Z( certAttributeMaxLen ) \
474 							int *certAttributeSize,
475 						 INOUT PKCS15_INFO *pkcs15infoPtr,
476 						 IN_HANDLE const CRYPT_HANDLE iCryptCert );
477 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
478 int readObjectAttributes( INOUT STREAM *stream,
479 						  INOUT PKCS15_INFO *pkcs15infoPtr,
480 						  IN_ENUM( PKCS15_OBJECT ) const PKCS15_OBJECT_TYPE type,
481 						  INOUT ERROR_INFO *errorInfo );
482 
483 /* Prototypes for functions in pkcs15_get/set.c */
484 
485 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
486 int initPKCS15get( INOUT KEYSET_INFO *keysetInfoPtr );
487 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
488 int initPKCS15set( INOUT KEYSET_INFO *keysetInfoPtr );
489 
490 /* Prototypes for functions in pkcs15_wr.c */
491 
492 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
493 int pkcs15Flush( INOUT STREAM *stream,
494 				 IN_ARRAY( noPkcs15objects ) const PKCS15_INFO *pkcs15info,
495 				 IN_LENGTH_SHORT const int noPkcs15objects );
496 
497 /* Prototypes for functions in pkcs15_rd.c */
498 
499 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4, 8, 9, 10, 11, 12 ) ) \
500 int readPublicKeyComponents( const PKCS15_INFO *pkcs15infoPtr,
501 							 IN_HANDLE const CRYPT_KEYSET iCryptKeysetCallback,
502 							 IN_ENUM( CRYPT_KEYID ) \
503 								const CRYPT_KEYID_TYPE keyIDtype,
504 							 IN_BUFFER( keyIDlength ) const void *keyID,
505 							 IN_LENGTH_KEYID const int keyIDlength,
506 							 const BOOLEAN publicComponentsOnly,
507 							 IN_HANDLE const CRYPT_DEVICE iDeviceObject,
508 							 OUT_HANDLE_OPT CRYPT_CONTEXT *iCryptContextPtr,
509 							 OUT_HANDLE_OPT CRYPT_CERTIFICATE *iDataCertPtr,
510 							 OUT_FLAGS_Z( ACTION_PERM ) int *pubkeyActionFlags,
511 							 OUT_FLAGS_Z( ACTION_PERM ) int *privkeyActionFlags,
512 							 INOUT ERROR_INFO *errorInfo );
513 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 6 ) ) \
514 int readPrivateKeyComponents( const PKCS15_INFO *pkcs15infoPtr,
515 							  IN_HANDLE const CRYPT_CONTEXT iPrivKeyContext,
516 							  IN_BUFFER_OPT( passwordLength ) \
517 									const void *password,
518 							  IN_LENGTH_NAME_Z const int passwordLength,
519 							  const BOOLEAN isStorageObject,
520 							  INOUT ERROR_INFO *errorInfo );
521 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 5 ) ) \
522 int readPkcs15Keyset( INOUT STREAM *stream,
523 					  OUT_ARRAY( maxNoPkcs15objects ) PKCS15_INFO *pkcs15info,
524 					  IN_LENGTH_SHORT const int maxNoPkcs15objects,
525 					  IN_LENGTH const long endPos,
526 					  INOUT ERROR_INFO *errorInfo );
527 
528 #endif /* _PKCS15_DEFINED */
529