summaryrefslogtreecommitdiffstats
path: root/include/iprt/crypto/store.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--include/iprt/crypto/store.h410
1 files changed, 410 insertions, 0 deletions
diff --git a/include/iprt/crypto/store.h b/include/iprt/crypto/store.h
new file mode 100644
index 00000000..c25e21e7
--- /dev/null
+++ b/include/iprt/crypto/store.h
@@ -0,0 +1,410 @@
+/** @file
+ * IPRT - Cryptographic (Certificate) Store.
+ */
+
+/*
+ * Copyright (C) 2006-2022 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 */
+