cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
pkcs12.h
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * PKCS #12 Definitions Header File *
4 * Copyright Peter Gutmann 1997-2009 *
5 * *
6 ****************************************************************************/
7 
8 #ifndef _PKCS12_DEFINED
9 
10 #define _PKCS12_DEFINED
11 
12 
13 #if defined( USE_PKCS12 ) && defined( _MSC_VER )
14  #pragma message( " Building with PKCS #12 enabled." )
15 #endif /* USE_PKCS12 with VC++ */
16 
17 /****************************************************************************
18 * *
19 * PKCS #12 Constants *
20 * *
21 ****************************************************************************/
22 
23 /* A PKCS #12 file can in theory contain multiple key and certificate
24  objects, however no normal implementation seems to use this capability
25  (a few oddball ones do, generally storing additional unencrypted
26  certificates alongside the private key and associated certificate).
27 
28  There are half a dozen different interpretations as to how multiple
29  entries are supposed to work, both in terms of how to interpret the format
30  and what to do with things like MACing, which can only use a single key
31  even if there are multiple different encryption keys used for the data.
32  In addition because of the complete abscence of key indexing information
33  there's no easy way to sort out which key or other object is used for
34  what.
35 
36  The code is written to handle multiple personalities like PKCS #15 and
37  PGP, but treats the presence or more than one private key as an error (in
38  practice it's a bit more complicated than that because of various PKCS
39  #12 vagaries, see the code in pkcs12_rd.c for more details) */
40 
41 #define MAX_PKCS12_OBJECTS 8
42 
43 /* The minimum number of keying iterations to use when deriving a key wrap
44  key from a password */
45 
46 #define MIN_KEYING_ITERATIONS 1000
47 
48 /* The minimum size of an object in a keyset, used for sanity-checking when
49  reading a keyset */
50 
51 #define MIN_OBJECT_SIZE 64
52 
53 /* Parameters for PKCS #12's homebrew password-derivation mechanism. The ID
54  values function as diversifiers when generating the same keying material
55  from a given password and in effect function as an extension of the salt */
56 
57 #define KEYWRAP_ID_WRAPKEY 1
58 #define KEYWRAP_ID_IV 2
59 #define KEYWRAP_ID_MACKEY 3
60 
61 #define KEYWRAP_SALTSIZE 8
62 
63 /* Flags for PKCS #12 object types */
64 
65 #define PKCS12_FLAG_NONE 0x00
66 #define PKCS12_FLAG_CERT 0x01 /* Object is certificate */
67 #define PKCS12_FLAG_ENCCERT 0x02 /* Object is encrypted cert. */
68 #define PKCS12_FLAG_PRIVKEY 0x04 /* Object is encrypted priv.key */
69 #define PKCS12_FLAG_MAX 0x07
70 
71 /****************************************************************************
72 * *
73 * PKCS #12 Types and Structures *
74 * *
75 ****************************************************************************/
76 
77 /* The following structure contains the information for a private key or
78  certificate object */
79 
80 typedef struct {
81  /* The overall object data and the location of the payload within it,
82  usually in the form of encrypted data */
84  const void *data; /* Object data */
85  int dataSize;
86  int payloadOffset, payloadSize; /* Payload within object data */
87 
88  /* Encryption information needed to process the payload */
89  CRYPT_ALGO_TYPE cryptAlgo; /* Encryption algorithm */
90  int keySize; /* Key size in bytes */
91  BUFFER( CRYPT_MAX_HASHSIZE, saltSize ) \
93  int saltSize; /* Password-derivation salt */
94  int iterations; /* Password-derivation iterations */
96 
97 /* The following structure contains the information for one personality,
98  which covers one or more of a private key and a certificate */
99 
100 typedef struct {
101  /* General information */
102  int flags; /* Object type information flags */
103  BUFFER( CRYPT_MAX_TEXTSIZE, labelLength ) \
104  char label[ CRYPT_MAX_TEXTSIZE + 8 ];/* PKCS #12 object label */
106  BUFFER( CRYPT_MAX_HASHSIZE, idLength ) \
107  BYTE id[ CRYPT_MAX_HASHSIZE + 8 ];/* PKCS #12 object ID */
108  int idLength;
109 
110  /* Key and certificate object information */
112 
113  /* Alongside the per-object security information, PKCS #12 files also
114  have a MAC for the keyset as a whole. This is supposedly optional
115  but many apps will reject the keyset (or even crash) if it's not
116  present.
117 
118  Since the same key is used for both the whole-keyset MAC and the
119  individual objects, we can really only have a single personality per
120  keyset. For now we deal with this by storing the MAC security
121  information alongside the other object information */
122  CRYPT_CONTEXT iMacContext; /* MAC context */
123  BUFFER( CRYPT_MAX_HASHSIZE, macSaltSize ) \
124  BYTE macSalt[ CRYPT_MAX_HASHSIZE + 8 ];
125  int macSaltSize; /* Salt for MAC key */
126  int macIterations; /* Number of iters.to derive MAC key */
127  BOOLEAN macInitialised; /* Whether MAC context has been set up */
128  } PKCS12_INFO;
129 
130 /****************************************************************************
131 * *
132 * PKCS #12 Functions *
133 * *
134 ****************************************************************************/
135 
136 /* Prototypes for functions in pkcs12.c */
137 
139 PKCS12_INFO *pkcs12FindEntry( IN_ARRAY( noPkcs12objects ) \
140  const PKCS12_INFO *pkcs12info,
143  IN_BUFFER_OPT( keyIDlength ) const void *keyID,
146 PKCS12_INFO *pkcs12FindFreeEntry( IN_ARRAY( noPkcs12objects ) \
147  const PKCS12_INFO *pkcs12info,
148  IN_LENGTH_SHORT const int noPkcs12objects,
150 STDC_NONNULL_ARG( ( 1 ) ) \
151 void pkcs12freeObjectEntry( INOUT PKCS12_OBJECT_INFO *pkcs12objectInfo );
152 STDC_NONNULL_ARG( ( 1 ) ) \
153 void pkcs12freeEntry( INOUT PKCS12_INFO *pkcs12info );
154 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 5 ) ) \
155 int createPkcs12KeyWrapContext( INOUT PKCS12_OBJECT_INFO *pkcs12objectInfo,
157  IN_BUFFER( passwordLength ) const char *password,
160  const BOOLEAN initParams );
161 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 5 ) ) \
162 int createPkcs12MacContext( INOUT PKCS12_INFO *pkcs12info,
163  IN_HANDLE const CRYPT_USER cryptOwner,
164  IN_BUFFER( passwordLength ) const char *password,
165  IN_LENGTH_NAME const int passwordLength,
167  const BOOLEAN initParams );
168 
169 /* Prototypes for functions in pkcs12_rd.c */
170 
171 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 5 ) ) \
172 int pkcs12ReadKeyset( INOUT STREAM *stream,
173  OUT_ARRAY( maxNoPkcs12objects ) PKCS12_INFO *pkcs12info,
175  IN_LENGTH const long endPos,
178 int initPKCS12get( INOUT KEYSET_INFO *keysetInfoPtr );
179 
180 /* Prototypes for functions in pkcs12_rd.c */
181 
182 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
183 int pkcs12ReadObject( INOUT STREAM *stream,
184  OUT PKCS12_INFO *pkcs12info,
185  const BOOLEAN isEncryptedCert,
187 
188 /* Prototypes for functions in pkcs12_wr.c */
189 
191 int initPKCS12set( INOUT KEYSET_INFO *keysetInfoPtr );
192 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
193 int pkcs12Flush( INOUT STREAM *stream,
194  IN_ARRAY( noPkcs12objects ) const PKCS12_INFO *pkcs12info,
195  IN_LENGTH_SHORT const int noPkcs12objects );
196 
197 #endif /* _PKCS12_DEFINED */