2 * IPRT - Cryptographic (Certificate) Store.
6 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
36 #ifndef IPRT_INCLUDED_crypto_store_h
37 #define IPRT_INCLUDED_crypto_store_h
38 #ifndef RT_WITHOUT_PRAGMA_ONCE
42 #include <iprt/crypto/x509.h>
43 #include <iprt/crypto/taf.h>
49 /** @defgroup grp_rt_crstore RTCrStore - Crypotgraphic (Certificate) Store.
50 * @ingroup grp_rt_crypto
56 * A certificate store search.
58 * Used by the store provider to keep track of the current location of a
61 typedef struct RTCRSTORECERTSEARCH
63 /** Opaque provider specific storage.
65 * Provider restriction: The provider is only allowed to use the two first
66 * entries for the find-all searches, because the front-end API may want the
67 * last two for implementing specific searches on top of it. */
68 uintptr_t auOpaque
[4];
69 } RTCRSTORECERTSEARCH
;
70 /** Pointer to a certificate store search. */
71 typedef RTCRSTORECERTSEARCH
*PRTCRSTORECERTSEARCH
;
75 * Info about a wanted certificate.
77 * All the search criteria are optional, but for a safe and efficient search
78 * it's recommended to specify all possible ones. If none are given, the search
81 * For use with RTCrStoreCertAddFromFishingExpedition and others.
83 typedef struct RTCRCERTWANTED
85 /** The certificate subject name, optional.
86 * The format is: "C=US, ST=California, L=Redwood Shores, O=Oracle Corporation" */
87 const char *pszSubject
;
88 /** The size of the DER (ASN.1) encoded certificate, optional (0). */
90 /** Set if abSha1 contains a valid SHA-1 fingerprint. */
91 bool fSha1Fingerprint
;
92 /** Set if abSha512 contains a valid SHA-512 fingerprint. */
93 bool fSha512Fingerprint
;
94 /** The SHA-1 fingerprint (of the encoded data). */
95 uint8_t abSha1
[RTSHA1_HASH_SIZE
];
96 /** The SHA-512 fingerprint (of the encoded data). */
97 uint8_t abSha512
[RTSHA512_HASH_SIZE
];
98 /** User pointer for directly associating other data with the entry.
99 * Subclassing the structure isn't possible because it's passed as an array. */
102 /** Pointer to a const certificat wanted structure. */
103 typedef RTCRCERTWANTED
const *PCRTCRCERTWANTED
;
107 * Standard store identifiers.
109 * This is a least common denominator approach to system specific certificate
110 * stores, could be extended to include things other than certificates later if
113 * Windows has lots of different stores, they'll be combined by the
114 * implementation, possibly leading to duplicates. The user stores on Windows
115 * seems to be unioned with the system (machine) stores.
117 * Linux may have different stores depending on the distro/version/installation,
118 * in which case we'll combine them, which will most likely lead to
119 * duplicates just like on windows. Haven't found any easily accessible
120 * per-user certificate stores on linux yet, so they'll all be empty.
122 * Mac OS X seems a lot simpler, at least from the GUI point of view. Each
123 * keychains as a "Certificates" folder (the "My Certificates" folder seems to
124 * only be a matching of "Keys" and "Certificates"). However, there are two
125 * system keychains that we need to combine, "System" and "System Roots". As
126 * with Windows and Linux, there is a possibility for duplicates here.
128 * On solaris we have currently no idea where to look for a certificate store,
129 * so that doesn't yet work.
131 * Because of the OS X setup, we do not provide any purpose specific
133 typedef enum RTCRSTOREID
135 /** Mandatory invalid zero value. */
136 RTCRSTOREID_INVALID
= 0,
137 /** Open the certificate store of the current user containing trusted
138 * CAs and certificates.
139 * @remarks This may or may not include all the certificates in the system
140 * store, that's host dependent. So, you better look in both. */
141 RTCRSTOREID_USER_TRUSTED_CAS_AND_CERTIFICATES
,
142 /** Open the certificate store of the system containg trusted CAs
143 * and certificates. */
144 RTCRSTOREID_SYSTEM_TRUSTED_CAS_AND_CERTIFICATES
,
145 /** Open the certificate store of the current user containing intermediate CAs.
146 * @remarks This may or may not include all the certificates in the system
147 * store, that's host dependent. So, you better look in both. */
148 RTCRSTOREID_USER_INTERMEDIATE_CAS
,
149 /** Open the certificate store of the system containg intermediate CAs. */
150 RTCRSTOREID_SYSTEM_INTERMEDIATE_CAS
,
151 /** End of valid values. */
153 /** Traditional enum type compression prevention hack. */
154 RTCRSTOREID_32BIT_HACK
= 0x7fffffff
158 * Creates a snapshot of a standard store.
160 * This will return an in-memory store containing all data from the given store.
161 * There will be no duplicates in this one.
163 * @returns IPRT status code.
164 * @param phStore Where to return the store handle. Use
165 * RTCrStoreRelease to release it.
166 * @param enmStoreId The store to snapshot.
167 * @param pErrInfo Where to return additional error/warning info.
170 RTDECL(int) RTCrStoreCreateSnapshotById(PRTCRSTORE phStore
, RTCRSTOREID enmStoreId
, PRTERRINFO pErrInfo
);
172 RTDECL(int) RTCrStoreCreateSnapshotOfUserAndSystemTrustedCAsAndCerts(PRTCRSTORE phStore
, PRTERRINFO pErrInfo
);
174 RTDECL(int) RTCrStoreCreateInMem(PRTCRSTORE phStore
, uint32_t cSizeHint
);
175 RTDECL(int) RTCrStoreCreateInMemEx(PRTCRSTORE phStore
, uint32_t cSizeHint
, RTCRSTORE hParentStore
);
177 RTDECL(uint32_t) RTCrStoreRetain(RTCRSTORE hStore
);
178 RTDECL(uint32_t) RTCrStoreRelease(RTCRSTORE hStore
);
179 RTDECL(PCRTCRCERTCTX
) RTCrStoreCertByIssuerAndSerialNo(RTCRSTORE hStore
, PCRTCRX509NAME pIssuer
, PCRTASN1INTEGER pSerialNo
);
182 * Add a certificate to the store.
184 * @returns IPRT status code.
185 * @retval VWRN_ALREADY_EXISTS if the certificate is already present and
186 * RTCRCERTCTX_F_ADD_IF_NOT_FOUND was specified.
187 * @retval VERR_WRITE_PROTECT if the store doesn't support adding.
188 * @param hStore The store to add the certificate to.
189 * @param fFlags RTCRCERTCTX_F_XXX. Encoding must be specified.
190 * RTCRCERTCTX_F_ADD_IF_NOT_FOUND is supported.
191 * @param pvSrc The encoded certificate bytes.
192 * @param cbSrc The size of the encoded certificate.
193 * @param pErrInfo Where to return additional error/warning info.
196 RTDECL(int) RTCrStoreCertAddEncoded(RTCRSTORE hStore
, uint32_t fFlags
, void const *pvSrc
, size_t cbSrc
, PRTERRINFO pErrInfo
);
199 * Add an X.509 packaged certificate to the store.
201 * @returns IPRT status code.
202 * @retval VWRN_ALREADY_EXISTS if the certificate is already present and
203 * RTCRCERTCTX_F_ADD_IF_NOT_FOUND was specified.
204 * @retval VERR_WRITE_PROTECT if the store doesn't support adding.
205 * @param hStore The store to add the certificate to.
206 * @param fFlags RTCRCERTCTX_F_XXX. Encoding must is optional,
207 * but must be RTCRCERTCTX_F_ENC_X509_DER if given.
208 * RTCRCERTCTX_F_ADD_IF_NOT_FOUND is supported.
209 * @param pCertificate The certificate to add. We may have to encode
210 * it, thus not const.
211 * @param pErrInfo Where to return additional error/warning info.
214 RTDECL(int) RTCrStoreCertAddX509(RTCRSTORE hStore
, uint32_t fFlags
, PRTCRX509CERTIFICATE pCertificate
, PRTERRINFO pErrInfo
);
217 * Adds certificates from files in the specified directory.
219 * @returns IPRT status code. Even when RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR is
220 * used, an error is returned as an error (and not a warning).
222 * @param hStore The store to add the certificate(s) to.
223 * @param fFlags RTCRCERTCTX_F_ADD_IF_NOT_FOUND and/or
224 * RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR.
225 * @param pszDir The path to the directory.
226 * @param paSuffixes List of suffixes of files to process.
227 * @param cSuffixes Number of suffixes. If this is 0, all files are
229 * @param pErrInfo Where to return additional error/warning info.
232 RTDECL(int) RTCrStoreCertAddFromDir(RTCRSTORE hStore
, uint32_t fFlags
, const char *pszDir
,
233 PCRTSTRTUPLE paSuffixes
, size_t cSuffixes
, PRTERRINFO pErrInfo
);
235 RTDECL(int) RTCrStoreCertAddWantedFromDir(RTCRSTORE hStore
, uint32_t fFlags
,
236 const char *pszDir
, PCRTSTRTUPLE paSuffixes
, size_t cSuffixes
,
237 PCRTCRCERTWANTED paWanted
, size_t cWanted
, bool *pafFound
, PRTERRINFO pErrInfo
);
240 * Adds certificates from the specified file.
242 * The supported file formats are:
243 * - PEM (base 64 blobs wrapped in -----BEGIN / END----). Support multiple
244 * certificates in one file.
245 * - Binary DER ASN.1 certificate. Only one per file.
246 * - Java key store version 2.
248 * @returns IPRT status code. Even when RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR is
249 * used, an error is returned as an error (and not a warning).
251 * @param hStore The store to add the certificate(s) to.
252 * @param fFlags RTCRCERTCTX_F_ADD_IF_NOT_FOUND and/or
253 * RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR.
254 * @param pszFilename The filename.
255 * @param pErrInfo Where to return additional error/warning info.
258 RTDECL(int) RTCrStoreCertAddFromFile(RTCRSTORE hStore
, uint32_t fFlags
, const char *pszFilename
, PRTERRINFO pErrInfo
);
260 RTDECL(int) RTCrStoreCertAddWantedFromFile(RTCRSTORE hStore
, uint32_t fFlags
, const char *pszFilename
,
261 PCRTCRCERTWANTED paWanted
, size_t cWanted
, bool *pafFound
, PRTERRINFO pErrInfo
);
264 * Adds certificates from the specified java key store file.
266 * @returns IPRT status code. Even when RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR is
267 * used, an error is returned as an error (and not a warning).
269 * @param hStore The store to add the certificate(s) to.
270 * @param fFlags RTCRCERTCTX_F_ADD_IF_NOT_FOUND and/or
271 * RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR.
272 * @param pszFilename The path to the JKS file.
273 * @param pErrInfo Where to return additional error/warning info.
276 RTDECL(int) RTCrStoreCertAddFromJavaKeyStore(RTCRSTORE hStore
, uint32_t fFlags
, const char *pszFilename
, PRTERRINFO pErrInfo
);
279 * Adds certificates from an in-memory java key store.
281 * @returns IPRT status code. Even when RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR is
282 * used, an error is returned as an error (and not a warning).
284 * @param hStore The store to add the certificate(s) to.
285 * @param fFlags RTCRCERTCTX_F_ADD_IF_NOT_FOUND and/or
286 * RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR.
287 * @param pvContent Pointer to the key store bytes.
288 * @param cbContent The size of the key store.
289 * @param pszErrorName The file name or whatever helpful indicator the
290 * caller want in the error messages.
291 * @param pErrInfo Where to return additional error/warning info.
294 RTDECL(int) RTCrStoreCertAddFromJavaKeyStoreInMem(RTCRSTORE hStore
, uint32_t fFlags
, void const *pvContent
, size_t cbContent
,
295 const char *pszErrorName
, PRTERRINFO pErrInfo
);
298 * Adds all certificates from @a hStoreSrc into @a hStore.
300 * @returns IPRT status code. Even when RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR is
301 * used, an error is returned as an error (and not a warning).
303 * @param hStore The destination store.
304 * @param fFlags RTCRCERTCTX_F_ADD_IF_NOT_FOUND and/or
305 * RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR.
306 * @param hStoreSrc The source store.
308 RTDECL(int) RTCrStoreCertAddFromStore(RTCRSTORE hStore
, uint32_t fFlags
, RTCRSTORE hStoreSrc
);
310 RTDECL(int) RTCrStoreCertAddWantedFromStore(RTCRSTORE hStore
, uint32_t fFlags
, RTCRSTORE hSrcStore
,
311 PCRTCRCERTWANTED paWanted
, size_t cWanted
, bool *pafFound
);
313 RTDECL(int) RTCrStoreCertCheckWanted(RTCRSTORE hStore
, PCRTCRCERTWANTED paWanted
, size_t cWanted
, bool *pafFound
);
316 RTDECL(int) RTCrStoreCertAddWantedFromFishingExpedition(RTCRSTORE hStore
, uint32_t fFlags
,
317 PCRTCRCERTWANTED paWanted
, size_t cWanted
,
318 bool *pafFound
, PRTERRINFO pErrInfo
);
321 * Exports the certificates in the store to a PEM file
323 * @returns IPRT status code.
324 * @param hStore The store which certificates should be exported.
325 * @param fFlags Reserved for the future, MBZ.
326 * @param pszFilename The name of the destination PEM file. This will
329 RTDECL(int) RTCrStoreCertExportAsPem(RTCRSTORE hStore
, uint32_t fFlags
, const char *pszFilename
);
332 * Counts the number of certificates in the store.
334 * @returns Certificate count on success, UINT32_MAX on failure.
335 * @param hStore The store which certificates should be counted.
337 RTDECL(uint32_t) RTCrStoreCertCount(RTCRSTORE hStore
);
339 RTDECL(int) RTCrStoreCertFindAll(RTCRSTORE hStore
, PRTCRSTORECERTSEARCH pSearch
);
340 RTDECL(int) RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280(RTCRSTORE hStore
, PCRTCRX509NAME pSubject
,
341 PRTCRSTORECERTSEARCH pSearch
);
342 RTDECL(PCRTCRCERTCTX
) RTCrStoreCertSearchNext(RTCRSTORE hStore
, PRTCRSTORECERTSEARCH pSearch
);
343 RTDECL(int) RTCrStoreCertSearchDestroy(RTCRSTORE hStore
, PRTCRSTORECERTSEARCH pSearch
);
345 RTDECL(int) RTCrStoreConvertToOpenSslCertStore(RTCRSTORE hStore
, uint32_t fFlags
, void **ppvOpenSslStore
, PRTERRINFO pErrInfo
);
346 RTDECL(int) RTCrStoreConvertToOpenSslCertStack(RTCRSTORE hStore
, uint32_t fFlags
, void **ppvOpenSslStack
, PRTERRINFO pErrInfo
);
352 /** @defgroup grp_rt_crcertctx RTCrCertCtx - (Store) Certificate Context.
357 * Certificate context.
359 * This is returned by the certificate store APIs and is part of a larger
360 * reference counted structure. All the data is read only.
362 typedef struct RTCRCERTCTX
364 /** Flags, RTCRCERTCTX_F_XXX. */
366 /** The size of the (DER) encoded certificate. */
368 /** Pointer to the (DER) encoded certificate. */
369 uint8_t const *pabEncoded
;
370 /** Pointer to the decoded X.509 representation of the certificate.
371 * This can be NULL when pTaInfo is present. */
372 PCRTCRX509CERTIFICATE pCert
;
373 /** Pointer to the decoded TrustAnchorInfo for the certificate. This can be
374 * NULL, even for trust anchors, as long as pCert isn't. */
375 PCRTCRTAFTRUSTANCHORINFO pTaInfo
;
376 /** Reserved for future use. */
380 /** @name RTCRCERTCTX_F_XXX.
382 /** Encoding mask. */
383 #define RTCRCERTCTX_F_ENC_MASK UINT32_C(0x000000ff)
384 /** X.509 certificate, DER encoded. */
385 #define RTCRCERTCTX_F_ENC_X509_DER UINT32_C(0x00000000)
386 /** RTF-5914 trust anchor info, DER encoded. */
387 #define RTCRCERTCTX_F_ENC_TAF_DER UINT32_C(0x00000001)
389 /** Extended certificate, DER encoded. */
390 #define RTCRCERTCTX_F_ENC_PKCS6_DER UINT32_C(0x00000002)
392 /** Mask containing the flags that ends up in the certificate context. */
393 #define RTCRCERTCTX_F_MASK UINT32_C(0x000000ff)
395 /** Add APIs: Add the certificate if not found. */
396 #define RTCRCERTCTX_F_ADD_IF_NOT_FOUND UINT32_C(0x00010000)
397 /** Add APIs: Continue on error when possible. */
398 #define RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR UINT32_C(0x00020000)
402 RTDECL(uint32_t) RTCrCertCtxRetain(PCRTCRCERTCTX pCertCtx
);
403 RTDECL(uint32_t) RTCrCertCtxRelease(PCRTCRCERTCTX pCertCtx
);
409 #endif /* !IPRT_INCLUDED_crypto_store_h */