diff options
Diffstat (limited to 'include/iprt/crypto/pem.h')
-rw-r--r-- | include/iprt/crypto/pem.h | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/include/iprt/crypto/pem.h b/include/iprt/crypto/pem.h new file mode 100644 index 00000000..7bd2c4fe --- /dev/null +++ b/include/iprt/crypto/pem.h @@ -0,0 +1,212 @@ +/** @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 <iprt/types.h> + + +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 */ + |