1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
|
/** @file
* IPRT - Cryptographic (Certificate) Store.
*/
/*
* Copyright (C) 2006-2019 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
#ifndef IPRT_INCLUDED_crypto_store_h
#define IPRT_INCLUDED_crypto_store_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif
#include <iprt/crypto/x509.h>
#include <iprt/crypto/taf.h>
#include <iprt/sha.h>
RT_C_DECLS_BEGIN
/** @defgroup grp_rt_crstore RTCrStore - Crypotgraphic (Certificate) Store.
* @ingroup grp_rt_crypto
* @{
*/
/**
* A certificate store search.
*
* Used by the store provider to keep track of the current location of a
* certificate search.
*/
typedef struct RTCRSTORECERTSEARCH
{
/** Opaque provider specific storage.
*
* Provider restriction: The provider is only allowed to use the two first
* entries for the find-all searches, because the front-end API may want the
* last two for implementing specific searches on top of it. */
uintptr_t auOpaque[4];
} RTCRSTORECERTSEARCH;
/** Pointer to a certificate store search. */
typedef RTCRSTORECERTSEARCH *PRTCRSTORECERTSEARCH;
/**
* Info about a wanted certificate.
*
* All the search criteria are optional, but for a safe and efficient search
* it's recommended to specify all possible ones. If none are given, the search
* function will fail.
*
* For use with RTCrStoreCertAddFromFishingExpedition and others.
*/
typedef struct RTCRCERTWANTED
{
/** The certificate subject name, optional.
* The format is: "C=US, ST=California, L=Redwood Shores, O=Oracle Corporation" */
const char *pszSubject;
/** The size of the DER (ASN.1) encoded certificate, optional (0). */
uint16_t cbEncoded;
/** Set if abSha1 contains a valid SHA-1 fingerprint. */
bool fSha1Fingerprint;
/** Set if abSha512 contains a valid SHA-512 fingerprint. */
bool fSha512Fingerprint;
/** The SHA-1 fingerprint (of the encoded data). */
uint8_t abSha1[RTSHA1_HASH_SIZE];
/** The SHA-512 fingerprint (of the encoded data). */
uint8_t abSha512[RTSHA512_HASH_SIZE];
/** User pointer for directly associating other data with the entry.
* Subclassing the structure isn't possible because it's passed as an array. */
void const *pvUser;
} RTCRCERTWANTED;
/** Pointer to a const certificat wanted structure. */
typedef RTCRCERTWANTED const *PCRTCRCERTWANTED;
/**
* Standard store identifiers.
*
* This is a least common denominator approach to system specific certificate
* stores, could be extended to include things other than certificates later if
* we need it.
*
* Windows has lots of different stores, they'll be combined by the
* implementation, possibly leading to duplicates. The user stores on Windows
* seems to be unioned with the system (machine) stores.
*
* Linux may have different stores depending on the distro/version/installation,
* in which case we'll combine them, which will most likely lead to
* duplicates just like on windows. Haven't found any easily accessible
* per-user certificate stores on linux yet, so they'll all be empty.
*
* Mac OS X seems a lot simpler, at least from the GUI point of view. Each
* keychains as a "Certificates" folder (the "My Certificates" folder seems to
* only be a matching of "Keys" and "Certificates"). However, there are two
* system keychains that we need to combine, "System" and "System Roots". As
* with Windows and Linux, there is a possibility for duplicates here.
*
* On solaris we have currently no idea where to look for a certificate store,
* so that doesn't yet work.
*
* Because of the OS X setup, we do not provide any purpose specific
*/
typedef enum RTCRSTOREID
{
/** Mandatory invalid zero value. */
RTCRSTOREID_INVALID = 0,
/** Open the certificate store of the current user containing trusted
* CAs and certificates.
* @remarks This may or may not include all the certificates in the system
* store, that's host dependent. So, you better look in both. */
RTCRSTOREID_USER_TRUSTED_CAS_AND_CERTIFICATES,
/** Open the certificate store of the system containg trusted CAs
* and certificates. */
RTCRSTOREID_SYSTEM_TRUSTED_CAS_AND_CERTIFICATES,
/** End of valid values. */
RTCRSTOREID_END,
/** Traditional enum type compression prevention hack. */
RTCRSTOREID_32BIT_HACK = 0x7fffffff
} RTCRSTOREID;
/**
* Creates a snapshot of a standard store.
*
* This will return an in-memory store containing all data from the given store.
* There will be no duplicates in this one.
*
* @returns IPRT status code.
* @retval VWRN_ALREADY_EXISTS if the certificate is already present and
* RTCRCERTCTX_F_ADD_IF_NOT_FOUND was specified.
* @param phStore Where to return the store handle. Use
* RTCrStoreRelease to release it.
* @param enmStoreId The store to snapshot.
* @param pErrInfo Where to return additional error/warning info.
* Optional.
*/
RTDECL(int) RTCrStoreCreateSnapshotById(PRTCRSTORE phStore, RTCRSTOREID enmStoreId, PRTERRINFO pErrInfo);
RTDECL(int) RTCrStoreCreateSnapshotOfUserAndSystemTrustedCAsAndCerts(PRTCRSTORE phStore, PRTERRINFO pErrInfo);
RTDECL(int) RTCrStoreCreateInMem(PRTCRSTORE phStore, uint32_t cSizeHint);
RTDECL(uint32_t) RTCrStoreRetain(RTCRSTORE hStore);
RTDECL(uint32_t) RTCrStoreRelease(RTCRSTORE hStore);
RTDECL(PCRTCRCERTCTX) RTCrStoreCertByIssuerAndSerialNo(RTCRSTORE hStore, PCRTCRX509NAME pIssuer, PCRTASN1INTEGER pSerialNo);
/**
* Add a certificate to the store.
*
* @returns IPRT status code.
* @retval VWRN_ALREADY_EXISTS if the certificate is already present and
* RTCRCERTCTX_F_ADD_IF_NOT_FOUND was specified.
* @retval VERR_WRITE_PROTECT if the store doesn't support adding.
* @param hStore The store to add the certificate to.
* @param fFlags RTCRCERTCTX_F_XXX. Encoding must be specified.
* RTCRCERTCTX_F_ADD_IF_NOT_FOUND is supported.
* @param pvSrc The encoded certificate bytes.
* @param cbSrc The size of the encoded certificate.
* @param pErrInfo Where to return additional error/warning info.
* Optional.
*/
RTDECL(int) RTCrStoreCertAddEncoded(RTCRSTORE hStore, uint32_t fFlags, void const *pvSrc, size_t cbSrc, PRTERRINFO pErrInfo);
/**
* Adds certificates from files in the specified directory.
*
* @returns IPRT status code. Even when RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR is
* used, an error is returned as an error (and not a warning).
*
* @param hStore The store to add the certificate(s) to.
* @param fFlags RTCRCERTCTX_F_ADD_IF_NOT_FOUND and/or
* RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR.
* @param pszDir The path to the directory.
* @param paSuffixes List of suffixes of files to process.
* @param cSuffixes Number of suffixes. If this is 0, all files are
* processed.
* @param pErrInfo Where to return additional error/warning info.
* Optional.
*/
RTDECL(int) RTCrStoreCertAddFromDir(RTCRSTORE hStore, uint32_t fFlags, const char *pszDir,
PCRTSTRTUPLE paSuffixes, size_t cSuffixes, PRTERRINFO pErrInfo);
RTDECL(int) RTCrStoreCertAddWantedFromDir(RTCRSTORE hStore, uint32_t fFlags,
const char *pszDir, PCRTSTRTUPLE paSuffixes, size_t cSuffixes,
PCRTCRCERTWANTED paWanted, size_t cWanted, bool *pafFound, PRTERRINFO pErrInfo);
/**
* Adds certificates from the specified file.
*
* The supported file formats are:
* - PEM (base 64 blobs wrapped in -----BEGIN / END----). Support multiple
* certificates in one file.
* - Binary DER ASN.1 certificate. Only one per file.
* - Java key store version 2.
*
* @returns IPRT status code. Even when RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR is
* used, an error is returned as an error (and not a warning).
*
* @param hStore The store to add the certificate(s) to.
* @param fFlags RTCRCERTCTX_F_ADD_IF_NOT_FOUND and/or
* RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR.
* @param pszFilename The filename.
* @param pErrInfo Where to return additional error/warning info.
* Optional.
*/
RTDECL(int) RTCrStoreCertAddFromFile(RTCRSTORE hStore, uint32_t fFlags, const char *pszFilename, PRTERRINFO pErrInfo);
RTDECL(int) RTCrStoreCertAddWantedFromFile(RTCRSTORE hStore, uint32_t fFlags, const char *pszFilename,
PCRTCRCERTWANTED paWanted, size_t cWanted, bool *pafFound, PRTERRINFO pErrInfo);
/**
* Adds certificates from the specified java key store file.
*
* @returns IPRT status code. Even when RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR is
* used, an error is returned as an error (and not a warning).
*
* @param hStore The store to add the certificate(s) to.
* @param fFlags RTCRCERTCTX_F_ADD_IF_NOT_FOUND and/or
* RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR.
* @param pszFilename The path to the JKS file.
* @param pErrInfo Where to return additional error/warning info.
* Optional.
*/
RTDECL(int) RTCrStoreCertAddFromJavaKeyStore(RTCRSTORE hStore, uint32_t fFlags, const char *pszFilename, PRTERRINFO pErrInfo);
/**
* Adds certificates from an in-memory java key store.
*
* @returns IPRT status code. Even when RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR is
* used, an error is returned as an error (and not a warning).
*
* @param hStore The store to add the certificate(s) to.
* @param fFlags RTCRCERTCTX_F_ADD_IF_NOT_FOUND and/or
* RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR.
* @param pvContent Pointer to the key store bytes.
* @param cbContent The size of the key store.
* @param pszErrorName The file name or whatever helpful indicator the
* caller want in the error messages.
* @param pErrInfo Where to return additional error/warning info.
* Optional.
*/
RTDECL(int) RTCrStoreCertAddFromJavaKeyStoreInMem(RTCRSTORE hStore, uint32_t fFlags, void const *pvContent, size_t cbContent,
const char *pszErrorName, PRTERRINFO pErrInfo);
/**
* Adds all certificates from @a hStoreSrc into @a hStore.
*
* @returns IPRT status code. Even when RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR is
* used, an error is returned as an error (and not a warning).
*
* @param hStore The destination store.
* @param fFlags RTCRCERTCTX_F_ADD_IF_NOT_FOUND and/or
* RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR.
* @param hStoreSrc The source store.
*/
RTDECL(int) RTCrStoreCertAddFromStore(RTCRSTORE hStore, uint32_t fFlags, RTCRSTORE hStoreSrc);
RTDECL(int) RTCrStoreCertAddWantedFromStore(RTCRSTORE hStore, uint32_t fFlags, RTCRSTORE hSrcStore,
PCRTCRCERTWANTED paWanted, size_t cWanted, bool *pafFound);
RTDECL(int) RTCrStoreCertCheckWanted(RTCRSTORE hStore, PCRTCRCERTWANTED paWanted, size_t cWanted, bool *pafFound);
RTDECL(int) RTCrStoreCertAddWantedFromFishingExpedition(RTCRSTORE hStore, uint32_t fFlags,
PCRTCRCERTWANTED paWanted, size_t cWanted,
bool *pafFound, PRTERRINFO pErrInfo);
/**
* Exports the certificates in the store to a PEM file
*
* @returns IPRT status code.
* @param hStore The store which certificates should be exported.
* @param fFlags Reserved for the future, MBZ.
* @param pszFilename The name of the destination PEM file. This will
* be truncated.
*/
RTDECL(int) RTCrStoreCertExportAsPem(RTCRSTORE hStore, uint32_t fFlags, const char *pszFilename);
/**
* Counts the number of certificates in the store.
*
* @returns Certificate count on success, UINT32_MAX on failure.
* @param hStore The store which certificates should be counted.
*/
RTDECL(uint32_t) RTCrStoreCertCount(RTCRSTORE hStore);
RTDECL(int) RTCrStoreCertFindAll(RTCRSTORE hStore, PRTCRSTORECERTSEARCH pSearch);
RTDECL(int) RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280(RTCRSTORE hStore, PCRTCRX509NAME pSubject,
PRTCRSTORECERTSEARCH pSearch);
RTDECL(PCRTCRCERTCTX) RTCrStoreCertSearchNext(RTCRSTORE hStore, PRTCRSTORECERTSEARCH pSearch);
RTDECL(int) RTCrStoreCertSearchDestroy(RTCRSTORE hStore, PRTCRSTORECERTSEARCH pSearch);
RTDECL(int) RTCrStoreConvertToOpenSslCertStore(RTCRSTORE hStore, uint32_t fFlags, void **ppvOpenSslStore);
RTDECL(int) RTCrStoreConvertToOpenSslCertStack(RTCRSTORE hStore, uint32_t fFlags, void **ppvOpenSslStack);
/** @} */
/** @defgroup grp_rt_crcertctx RTCrCertCtx - (Store) Certificate Context.
* @{ */
/**
* Certificate context.
*
* This is returned by the certificate store APIs and is part of a larger
* reference counted structure. All the data is read only.
*/
typedef struct RTCRCERTCTX
{
/** Flags, RTCRCERTCTX_F_XXX. */
uint32_t fFlags;
/** The size of the (DER) encoded certificate. */
uint32_t cbEncoded;
/** Pointer to the (DER) encoded certificate. */
uint8_t const *pabEncoded;
/** Pointer to the decoded X.509 representation of the certificate.
* This can be NULL when pTaInfo is present. */
PCRTCRX509CERTIFICATE pCert;
/** Pointer to the decoded TrustAnchorInfo for the certificate. This can be
* NULL, even for trust anchors, as long as pCert isn't. */
PCRTCRTAFTRUSTANCHORINFO pTaInfo;
/** Reserved for future use. */
void *paReserved[2];
} RTCRCERTCTX;
/** @name RTCRCERTCTX_F_XXX.
* @{ */
/** Encoding mask. */
#define RTCRCERTCTX_F_ENC_MASK UINT32_C(0x000000ff)
/** X.509 certificate, DER encoded. */
#define RTCRCERTCTX_F_ENC_X509_DER UINT32_C(0x00000000)
/** RTF-5914 trust anchor info, DER encoded. */
#define RTCRCERTCTX_F_ENC_TAF_DER UINT32_C(0x00000001)
#if 0
/** Extended certificate, DER encoded. */
#define RTCRCERTCTX_F_ENC_PKCS6_DER UINT32_C(0x00000002)
#endif
/** Mask containing the flags that ends up in the certificate context. */
#define RTCRCERTCTX_F_MASK UINT32_C(0x000000ff)
/** Add APIs: Add the certificate if not found. */
#define RTCRCERTCTX_F_ADD_IF_NOT_FOUND UINT32_C(0x00010000)
/** Add APIs: Continue on error when possible. */
#define RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR UINT32_C(0x00020000)
/** @} */
RTDECL(uint32_t) RTCrCertCtxRetain(PCRTCRCERTCTX pCertCtx);
RTDECL(uint32_t) RTCrCertCtxRelease(PCRTCRCERTCTX pCertCtx);
/** @} */
RT_C_DECLS_END
#endif /* !IPRT_INCLUDED_crypto_store_h */
|