/** @file * IPRT - Crypto - PEM-file Reader & Writer. */ /* * 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_pem_h #define IPRT_INCLUDED_crypto_pem_h #ifndef RT_WITHOUT_PRAGMA_ONCE # pragma once #endif #include RT_C_DECLS_BEGIN /** @defgroup grp_rt_spc RTCrPem - PEM-file Reader & Writer * @ingroup grp_rt_crypto * @{ */ /** * One PEM marker word (use RT_STR_TUPLE to initialize). */ typedef struct RTCRPEMMARKERWORD { /** The word string. */ const char *pszWord; /** The length. */ uint32_t cchWord; } RTCRPEMMARKERWORD; /** Pointer to a const marker word. */ typedef RTCRPEMMARKERWORD const *PCRTCRPEMMARKERWORD; /** * A PEM marker. * * This is an array of words with lengths, optimized for avoid unnecessary * strlen() while searching the file content. It is ASSUMED that all PEM * section markers starts with either 'BEGIN' or 'END', followed by the words * in the this structure. */ typedef struct RTCRPEMMARKER { /** Pointer to an array of marker words. */ PCRTCRPEMMARKERWORD paWords; /** Number of works in the array papszWords points to. */ uint32_t cWords; } RTCRPEMMARKER; /** Pointer to a const PEM marker. */ typedef RTCRPEMMARKER const *PCRTCRPEMMARKER; /** * A PEM field. */ typedef struct RTCRPEMFIELD { /** Pointer to the next field. */ struct RTCRPEMFIELD const *pNext; /** The field value. */ char const *pszValue; /** The field value length. */ size_t cchValue; /** The field name length. */ size_t cchName; /** The field name. */ char szName[RT_FLEXIBLE_ARRAY]; } RTCRPEMFIELD; /** Pointer to a PEM field. */ typedef RTCRPEMFIELD *PRTCRPEMFIELD; /** Pointer to a const PEM field. */ typedef RTCRPEMFIELD const *PCRTCRPEMFIELD; /** * A PEM section. * * The API works on linked lists of these. */ typedef struct RTCRPEMSECTION { /** Pointer to the next file section. */ struct RTCRPEMSECTION const *pNext; /** The marker for this section. NULL if binary file. */ PCRTCRPEMMARKER pMarker; /** Pointer to the binary data. */ uint8_t *pbData; /** The size of the binary data. */ size_t cbData; /** List of fields, NULL if none. */ PCRTCRPEMFIELD pFieldHead; /** Set if RTCRPEMREADFILE_F_SENSITIVE was specified. */ bool fSensitive; } RTCRPEMSECTION; /** Pointer to a PEM section. */ typedef RTCRPEMSECTION *PRTCRPEMSECTION; /** Pointer to a const PEM section. */ typedef RTCRPEMSECTION const *PCRTCRPEMSECTION; /** * Frees sections returned by RTCrPemReadFile and RTCrPemParseContent. * @returns IPRT status code. * @param pSectionHead The first section. */ RTDECL(int) RTCrPemFreeSections(PCRTCRPEMSECTION pSectionHead); /** * Parses the given data and returns a list of binary sections. * * If the file isn't an ASCII file or if no markers were found, the entire file * content is returned as one single section (with pMarker = NULL). * * @returns IPRT status code. * @retval VINF_EOF if the file is empty. The @a ppSectionHead value will be * NULL. * @retval VWRN_NOT_FOUND no section was found and RTCRPEMREADFILE_F_ONLY_PEM * is specified. The @a ppSectionHead value will be NULL. * * @param pvContent The content bytes to parse. * @param cbContent The number of content bytes. * @param fFlags RTCRPEMREADFILE_F_XXX. * @param paMarkers Array of one or more section markers to look for. * @param cMarkers Number of markers in the array. * @param ppSectionHead Where to return the head of the section list. Call * RTCrPemFreeSections to free. * @param pErrInfo Where to return extend error info. Optional. */ RTDECL(int) RTCrPemParseContent(void const *pvContent, size_t cbContent, uint32_t fFlags, PCRTCRPEMMARKER paMarkers, size_t cMarkers, PCRTCRPEMSECTION *ppSectionHead, PRTERRINFO pErrInfo); /** * Reads the content of the given file and returns a list of binary sections * found in the file. * * If the file isn't an ASCII file or if no markers were found, the entire file * content is returned as one single section (with pMarker = NULL). * * @returns IPRT status code. * @retval VINF_EOF if the file is empty. The @a ppSectionHead value will be * NULL. * @retval VWRN_NOT_FOUND no section was found and RTCRPEMREADFILE_F_ONLY_PEM * is specified. The @a ppSectionHead value will be NULL. * * @param pszFilename The path to the file to read. * @param fFlags RTCRPEMREADFILE_F_XXX. * @param paMarkers Array of one or more section markers to look for. * @param cMarkers Number of markers in the array. * @param ppSectionHead Where to return the head of the section list. Call * RTCrPemFreeSections to free. * @param pErrInfo Where to return extend error info. Optional. */ RTDECL(int) RTCrPemReadFile(const char *pszFilename, uint32_t fFlags, PCRTCRPEMMARKER paMarkers, size_t cMarkers, PCRTCRPEMSECTION *ppSectionHead, PRTERRINFO pErrInfo); /** @name RTCRPEMREADFILE_F_XXX - Flags for RTCrPemReadFile and * RTCrPemParseContent. * @{ */ /** Continue on encoding error. */ #define RTCRPEMREADFILE_F_CONTINUE_ON_ENCODING_ERROR RT_BIT(0) /** Only PEM sections, no binary fallback. */ #define RTCRPEMREADFILE_F_ONLY_PEM RT_BIT(1) /** Sensitive data, use the safer allocator. */ #define RTCRPEMREADFILE_F_SENSITIVE RT_BIT(2) /** Valid flags. */ #define RTCRPEMREADFILE_F_VALID_MASK UINT32_C(0x00000007) /** @} */ /** * Finds the beginning of first PEM section using the specified markers. * * This will not look any further than the first section. Nor will it check for * binaries. * * @returns Pointer to the "-----BEGIN XXXX" sequence on success. * NULL if not found. * @param pvContent The content bytes to parse. * @param cbContent The number of content bytes. * @param paMarkers Array of one or more section markers to look for. * @param cMarkers Number of markers in the array. */ RTDECL(const char *) RTCrPemFindFirstSectionInContent(void const *pvContent, size_t cbContent, PCRTCRPEMMARKER paMarkers, size_t cMarkers); /** @} */ RT_C_DECLS_END #endif /* !IPRT_INCLUDED_crypto_pem_h */