cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
pkcs15.h
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * PKCS #15 Definitions Header File *
4 * Copyright Peter Gutmann 1996-2009 *
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 /* Usually a PKCS #15 personality consists of a collection of related PKCS
66  #15 objects (typically a public and private key and a certificate), but
67  sometimes we have personalities that consist only of a certificate and
68  little other information (for example a trusted CA root certificate,
69  which contains no user-supplied information such as a label). The
70  following types of personality are handled for PKCS #15 files */
71 
72 typedef enum {
73  PKCS15_SUBTYPE_NONE, /* Non-personality */
74  PKCS15_SUBTYPE_NORMAL, /* Standard personality, keys+optional cert */
75  PKCS15_SUBTYPE_CERT, /* Standalone certificate */
76  PKCS15_SUBTYPE_SECRETKEY, /* Secret key */
77  PKCS15_SUBTYPE_DATA, /* Pre-encoded cryptlib-specific data */
80 
81 /* The types of object that we can find in a PKCS #15 file */
82 
87 
88 /* The types of key identifiers that we can find attached to an object */
89 
95 
96 /* PKCS #15 key usage flags, a complex mixture of PKCS #11 and some bits of
97  X.509 */
98 
99 #define PKCS15_USAGE_ENCRYPT 0x0001
100 #define PKCS15_USAGE_DECRYPT 0x0002
101 #define PKCS15_USAGE_SIGN 0x0004
102 #define PKCS15_USAGE_SIGNRECOVER 0x0008
103 #define PKCS15_USAGE_WRAP 0x0010
104 #define PKCS15_USAGE_UNWRAP 0x0020
105 #define PKCS15_USAGE_VERIFY 0x0040
106 #define PKCS15_USAGE_VERIFYRECOVER 0x0080
107 #define PKCS15_USAGE_DERIVE 0x0100
108 #define PKCS15_USAGE_NONREPUDIATION 0x0200
109 
110 /* Symbolic values for range checking of the usage flags */
111 
112 #define PKSC15_USAGE_FLAG_NONE 0x0000
113 #define PKCS15_USAGE_FLAG_MAX 0x03FF
114 
115 /* PKCS #15 flags that can't be set for public keys. We use this as a mask
116  to derive public-key flags from private key ones */
117 
118 #define PUBKEY_USAGE_MASK ~( PKCS15_USAGE_DECRYPT | PKCS15_USAGE_SIGN | \
119  PKCS15_USAGE_SIGNRECOVER | PKCS15_USAGE_UNWRAP )
120 
121 /* PKCS #15 usage types for encryption and signature keys. We use these when
122  looking specifically for signing or encryption keys */
123 
124 #define ENCR_USAGE_MASK ( PKCS15_USAGE_ENCRYPT | PKCS15_USAGE_DECRYPT | \
125  PKCS15_USAGE_WRAP | PKCS15_USAGE_UNWRAP )
126 #define SIGN_USAGE_MASK ( PKCS15_USAGE_SIGN | PKCS15_USAGE_SIGNRECOVER | \
127  PKCS15_USAGE_VERIFY | PKCS15_USAGE_VERIFYRECOVER | \
128  PKCS15_USAGE_NONREPUDIATION )
129 
130 /* The access flags for various types of key objects. For a public key we
131  set 'extractable', for a private key we set 'sensitive',
132  'alwaysSensitive', and 'neverExtractable' */
133 
134 #define KEYATTR_ACCESS_PUBLIC 0x02 /* 00010b */
135 #define KEYATTR_ACCESS_PRIVATE 0x0D /* 01101b */
136 
137 /* When adding a public key and/or certificate to a PKCS #15 collection we
138  have to be able to cleanly handle the addition of arbitrary collections of
139  potentially overlapping objects. Since a public key is a subset of the
140  data in a certificate, if we're adding a certificate + public key pair
141  the certificate data overrides the public key, which isn't added at all.
142  This leads to some rather convoluted logic for deciding what needs
143  updating and under which conditions. The actions taken are:
144 
145  key only: if present
146  return( CRYPT_ERROR_DUPLICATE )
147  else
148  add key;
149  cert only: if present
150  return( CRYPT_ERROR_DUPLICATE );
151  elif( matching key present )
152  add, delete key data;
153  elif( trusted certificate )
154  add as trusted certificate;
155  else
156  error;
157  key+cert: if key present and certificate present
158  return( CRYPT_ERROR_DUPLICATE );
159  delete key;
160  if certificate present -> don't add certificate;
161 
162  The following values specify the action to be taken when adding a
163  certificate */
164 
165 typedef enum {
166  CERTADD_NONE, /* No certificate add action */
167  CERTADD_UPDATE_EXISTING,/* Update existing key info with a certificate */
168  CERTADD_NORMAL, /* Add a certificate for which no key info present */
169  CERTADD_STANDALONE_CERT,/* Add a standalone certificate not assoc'd with a key */
170  CERTADD_LAST /* Last valid certificate add action */
171  } CERTADD_TYPE;
172 
173 /* Since PKCS #15 uses more key ID types than are used by the rest of
174  cryptlib, we extend the standard range with PKCS15-only types */
175 
176 #define CRYPT_KEYIDEX_ID CRYPT_KEYID_LAST
177 #define CRYPT_KEYIDEX_SUBJECTNAMEID ( CRYPT_KEYID_LAST + 1 )
178 
179 /* The minimum size of an object in a keyset, used for sanity-checking when
180  reading a keyset */
181 
182 #define MIN_OBJECT_SIZE 16
183 
184 /* When writing attributes it's useful to have a fixed-size buffer rather
185  than having to mess around with all sorts of variable-length structures,
186  the following value defines the maximum size of the attribute data that
187  we can write (that is, the I/O stream is opened with this size and
188  generates a CRYPT_ERROR_OVERFLOW if we go beyond this). The maximum-
189  length buffer contents are two CRYPT_MAX_TEXTSIZE strings, about half a
190  dozen hashes (as IDs for subject, issuer, and so on), and a few odd bits
191  and pieces so this is plenty */
192 
193 #define KEYATTR_BUFFER_SIZE 512
194 
195 /****************************************************************************
196 * *
197 * PKCS #15 Types and Structures *
198 * *
199 ****************************************************************************/
200 
201 /* The following structure contains the the information for one personality,
202  which covers one or more of a private key, public key, and certificate */
203 
204 typedef struct {
205  /* General information on the personality: The subtype, a local unique
206  identifier which is easier to manage than the iD (this is used when
207  enumerating PKCS #15 items in a keyset, the last-read-item entry is
208  set to the index value), the PKCS #15 object label, and the PKCS #15
209  object ID and key ID (which is usually the same as the object ID) */
210  PKCS15_SUBTYPE type; /* Personality subtype */
211  int index; /* Unique value for this personality */
212  BUFFER( CRYPT_MAX_TEXTSIZE, labelLength ) \
213  char label[ CRYPT_MAX_TEXTSIZE + 8 ];/* PKCS #15 object label */
215  BUFFER( CRYPT_MAX_HASHSIZE, iDlength ) \
216  BYTE iD[ CRYPT_MAX_HASHSIZE + 8 ];
219  int iDlength, keyIDlength; /* PKCS #15 object ID and key ID */
220 
221  /* Certificate-related ID information: Hash of the issuer name, subject
222  name, and issuerAndSerialNumber, and PGP key IDs */
223  BUFFER( KEYID_SIZE, iAndSIDlength ) \
224  BYTE iAndSID[ KEYID_SIZE + 8 ];
225  BUFFER( KEYID_SIZE, subjectNameIDlength ) \
226  BYTE subjectNameID[ KEYID_SIZE + 8 ];
227  BUFFER( KEYID_SIZE, issuerNameIDlength ) \
228  BYTE issuerNameID[ KEYID_SIZE + 8 ];
229  BUFFER( KEYID_SIZE, pgp2KeyIDlength ) \
230  BYTE pgp2KeyID[ PGP_KEYID_SIZE + 8 ];
231  BUFFER( KEYID_SIZE, openPGPKeyIDlength ) \
232  BYTE openPGPKeyID[ PGP_KEYID_SIZE + 8 ];
233  int iAndSIDlength, subjectNameIDlength, issuerNameIDlength;
234  int pgp2KeyIDlength, openPGPKeyIDlength;
235 
236  /* Key/certificate object data */
237  BUFFER_OPT_FIXED( pubKeyDataSize ) \
238  void *pubKeyData;
239  BUFFER_OPT_FIXED( privKeyDataSize ) \
240  void *privKeyData;
241  BUFFER_OPT_FIXED( certDataSize ) \
242  void *certData; /* Encoded object data */
243  int pubKeyDataSize, privKeyDataSize, certDataSize;
244  int pubKeyOffset, privKeyOffset, certOffset;
245  /* Offset of payload in data */
246  int pubKeyUsage, privKeyUsage; /* Permitted usage for the key */
247  int trustedUsage; /* Usage which key is trusted for */
248  BOOLEAN implicitTrust; /* Whether certificate is implicitly trusted */
249  time_t validFrom, validTo; /* Key/certificate validity information */
250 
251  /* Secret-key object data */
252  BUFFER_OPT_FIXED( secretKeyDataSize ) \
253  void *secretKeyData; /* Encoded object data */
254  int secretKeyDataSize, secretKeyOffset;
255 
256  /* Data object data */
257  CRYPT_ATTRIBUTE_TYPE dataType; /* Type of the encoded object data */
258  BUFFER_OPT_FIXED( dataDataSize ) \
259  void *dataData; /* Encoded object data */
260  int dataDataSize, dataOffset;
261  } PKCS15_INFO;
262 
263 /****************************************************************************
264 * *
265 * PKCS #15 ASN.1 Tags *
266 * *
267 ****************************************************************************/
268 
269 /* Context-specific tags for object types */
270 
274 
275 /* Context-specific tags for the PublicKeyInfo record */
276 
278 
279 /* Context-specific tags for the object record */
280 
282 
283 /* Context-specific tags for the object value record */
284 
287 
288 /* Context-specific tags for the class attributes record */
289 
293 
294 /* Context-specific tags for the public/private key objects record */
295 
297 
298 /* Context-specific tags for the data objects record */
299 
301 
302 /****************************************************************************
303 * *
304 * PKCS #15 Functions *
305 * *
306 ****************************************************************************/
307 
308 /* Utility functions in pkcs15.c */
309 
310 CHECK_RETVAL STDC_NONNULL_ARG( ( 3, 5 ) ) \
311 int getCertID( IN_HANDLE const CRYPT_HANDLE iCryptHandle,
313  OUT_BUFFER( nameIdMaxLen, *nameIdLen ) BYTE *nameID,
314  IN_LENGTH_SHORT_MIN( KEYID_SIZE ) const int nameIdMaxLen,
317 PKCS15_INFO *findEntry( IN_ARRAY( noPkcs15objects ) const PKCS15_INFO *pkcs15info,
319  IN_ENUM( CRYPT_KEYID ) const CRYPT_KEYID_TYPE keyIDtype,
320  IN_BUFFER_OPT( keyIDlength ) const void *keyID,
322  IN_FLAGS_Z( KEYMGMT ) const int requestedUsage );
324 PKCS15_INFO *findFreeEntry( IN_ARRAY( noPkcs15objects ) \
325  const PKCS15_INFO *pkcs15info,
326  IN_LENGTH_SHORT const int noPkcs15objects,
328 STDC_NONNULL_ARG( ( 1 ) ) \
329 void pkcs15freeEntry( INOUT PKCS15_INFO *pkcs15info );
331 int getValidityInfo( INOUT PKCS15_INFO *pkcs15info,
333 
334 /* Prototypes for functions in pkcs15_add.c */
335 
337 int getKeyTypeTag( IN_HANDLE_OPT const CRYPT_CONTEXT cryptContext,
339  OUT int *tag );
340 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
341 int addConfigData( IN_ARRAY( noPkcs15objects ) PKCS15_INFO *pkcs15info,
342  IN_LENGTH_SHORT const int noPkcs15objects,
344  IN_BUFFER( dataLength ) const char *data,
347 int addSecretKey( IN_ARRAY( noPkcs15objects ) PKCS15_INFO *pkcs15info,
348  IN_LENGTH_SHORT const int noPkcs15objects,
350 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 11 ) ) \
351 int pkcs15AddKey( INOUT PKCS15_INFO *pkcs15infoPtr,
352  IN_HANDLE const CRYPT_HANDLE iCryptHandle,
353  IN_BUFFER_OPT( passwordLength ) const void *password,
358  const BOOLEAN isStorageObject,
360 
361 /* Prototypes for functions in pkcs15_adpb.c */
362 
363 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 6 ) ) \
364 int pkcs15AddCert( INOUT PKCS15_INFO *pkcs15infoPtr,
367  const void *privKeyAttributes,
369  IN_ENUM( CERTADD ) const CERTADD_TYPE certAddType,
371 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
372 int pkcs15AddCertChain( INOUT PKCS15_INFO *pkcs15info,
373  IN_LENGTH_SHORT const int noPkcs15objects,
374  IN_HANDLE const CRYPT_CERTIFICATE iCryptCert,
376 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 8 ) ) \
377 int pkcs15AddPublicKey( INOUT PKCS15_INFO *pkcs15infoPtr,
380  const void *pubKeyAttributes,
383  IN_LENGTH_PKC const int modulusSize,
384  const BOOLEAN isStorageObject,
386 
387 /* Prototypes for functions in pkcs15_adpr.c. The private-key attribute
388  functions have to be accessible externally because adding or changing a
389  certificate for a private key can update the private-key attributes */
390 
391 STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
392 void updatePrivKeyAttributes( INOUT PKCS15_INFO *pkcs15infoPtr,
394  void *newPrivKeyData,
395  IN_LENGTH_SHORT_MIN( 16 ) \
396  const int newPrivKeyDataSize,
397  IN_BUFFER( privKeyAttributeSize ) \
398  const void *privKeyAttributes,
399  IN_LENGTH_SHORT const int privKeyAttributeSize,
400  IN_LENGTH_SHORT const int privKeyInfoSize,
401  IN_TAG const int keyTypeTag );
402 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
403 int calculatePrivkeyStorage( OUT_BUFFER_ALLOC_OPT( *newPrivKeyDataSize ) \
404  void **newPrivKeyDataPtr,
405  OUT_LENGTH_SHORT_Z int *newPrivKeyDataSize,
407  const void *origPrivKeyData,
409  IN_LENGTH_SHORT const int privKeySize,
410  IN_LENGTH_SHORT const int privKeyAttributeSize,
411  IN_LENGTH_SHORT const int extraDataSize );
412 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 6, 11 ) ) \
413 int pkcs15AddPrivateKey( INOUT PKCS15_INFO *pkcs15infoPtr,
416  IN_BUFFER_OPT( passwordLength ) const char *password,
418  IN_BUFFER( privKeyAttributeSize ) \
419  const void *privKeyAttributes,
420  IN_LENGTH_SHORT const int privKeyAttributeSize,
422  IN_LENGTH_PKC const int modulusSize,
423  const BOOLEAN isStorageObject,
425 
426 /* Prototypes for functions in pkcs15_atrd.c/pkcs15_atwr.c */
427 
428 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4, 6, 7 ) ) \
429 int writeKeyAttributes( OUT_BUFFER( privKeyAttributeMaxLen, \
430  *privKeyAttributeSize )
431  void *privKeyAttributes,
432  IN_LENGTH_SHORT_MIN( 16 ) \
433  const int privKeyAttributeMaxLen,
434  OUT_LENGTH_SHORT_Z int *privKeyAttributeSize,
435  OUT_BUFFER( pubKeyAttributeMaxLen, \
437  void *pubKeyAttributes,
438  IN_LENGTH_SHORT_MIN( 16 ) \
439  const int pubKeyAttributeMaxLen,
441  INOUT PKCS15_INFO *pkcs15infoPtr,
442  IN_HANDLE const CRYPT_HANDLE iCryptContext );
443 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
444 int writeCertAttributes( OUT_BUFFER( certAttributeMaxLen, *certAttributeSize ) \
446  IN_LENGTH_SHORT_MIN( 16 ) const int certAttributeMaxLen,
448  INOUT PKCS15_INFO *pkcs15infoPtr,
449  IN_HANDLE const CRYPT_HANDLE iCryptCert );
450 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
451 int readObjectAttributes( INOUT STREAM *stream,
452  INOUT PKCS15_INFO *pkcs15infoPtr,
453  IN_ENUM( PKCS15_OBJECT ) const PKCS15_OBJECT_TYPE type,
455 
456 /* Prototypes for functions in pkcs15_get/set.c */
457 
459 int initPKCS15get( INOUT KEYSET_INFO *keysetInfoPtr );
461 int initPKCS15set( INOUT KEYSET_INFO *keysetInfoPtr );
462 
463 /* Prototypes for functions in pkcs15_wr.c */
464 
465 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
466 int pkcs15Flush( INOUT STREAM *stream,
467  IN_ARRAY( noPkcs15objects ) const PKCS15_INFO *pkcs15info,
468  IN_LENGTH_SHORT const int noPkcs15objects );
469 
470 /* Prototypes for functions in pkcs15_rd.c */
471 
472 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4, 8, 9, 10, 11, 12 ) ) \
473 int readPublicKeyComponents( const PKCS15_INFO *pkcs15infoPtr,
475  IN_ENUM( CRYPT_KEYID ) \
476  const CRYPT_KEYID_TYPE keyIDtype,
477  IN_BUFFER( keyIDlength ) const void *keyID,
478  IN_LENGTH_KEYID const int keyIDlength,
483  OUT_FLAGS_Z( ACTION ) int *pubkeyActionFlags,
484  OUT_FLAGS_Z( ACTION ) int *privkeyActionFlags,
486 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 6 ) ) \
487 int readPrivateKeyComponents( const PKCS15_INFO *pkcs15infoPtr,
488  IN_HANDLE const CRYPT_CONTEXT iPrivKeyContext,
489  IN_BUFFER_OPT( passwordLength ) \
490  const void *password,
491  IN_LENGTH_NAME_Z const int passwordLength,
492  const BOOLEAN isStorageObject,
494 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 5 ) ) \
495 int readPkcs15Keyset( INOUT STREAM *stream,
496  OUT_ARRAY( maxNoPkcs15objects ) PKCS15_INFO *pkcs15info,
498  IN_LENGTH const long endPos,
500 
501 #endif /* _PKCS15_DEFINED */