summaryrefslogtreecommitdiffstats
path: root/include/iprt/crypto/store.h
blob: 729019ecd966b8e6b950d49cb64afa0768753e75 (plain)
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
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
/** @file
 * IPRT - Cryptographic (Certificate) Store.
 */

/*
 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
 *
 * This file is part of VirtualBox base platform packages, as
 * available from https://www.virtualbox.org.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, in version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses>.
 *
 * The contents of this file may alternatively be used under the terms
 * of the Common Development and Distribution License Version 1.0
 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
 * in the VirtualBox 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.
 *
 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
 */

#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,
    /** Open the certificate store of the current user containing intermediate CAs.
     * @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_INTERMEDIATE_CAS,
    /** Open the certificate store of the system containg intermediate CAs. */
    RTCRSTOREID_SYSTEM_INTERMEDIATE_CAS,
    /** 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.
 * @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(int) RTCrStoreCreateInMemEx(PRTCRSTORE phStore, uint32_t cSizeHint, RTCRSTORE hParentStore);

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);

/**
 * Add an X.509 packaged 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 is optional,
 *                              but must be RTCRCERTCTX_F_ENC_X509_DER if given.
 *                              RTCRCERTCTX_F_ADD_IF_NOT_FOUND is supported.
 * @param   pCertificate        The certificate to add.  We may have to encode
 *                              it, thus not const.
 * @param   pErrInfo            Where to return additional error/warning info.
 *                              Optional.
 */
RTDECL(int) RTCrStoreCertAddX509(RTCRSTORE hStore, uint32_t fFlags, PRTCRX509CERTIFICATE pCertificate, 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, PRTERRINFO pErrInfo);
RTDECL(int) RTCrStoreConvertToOpenSslCertStack(RTCRSTORE hStore, uint32_t fFlags, void **ppvOpenSslStack, PRTERRINFO pErrInfo);


/** @} */


/** @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 */