VirtualBox

source: vbox/trunk/include/iprt/crypto/pem.h

Last change on this file was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.7 KB
Line 
1/** @file
2 * IPRT - Crypto - PEM-file Reader & Writer.
3 */
4
5/*
6 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
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
14 * License.
15 *
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.
20 *
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>.
23 *
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.
29 *
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.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef IPRT_INCLUDED_crypto_pem_h
37#define IPRT_INCLUDED_crypto_pem_h
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <iprt/types.h>
43#include <iprt/asn1.h> /* PRTASN1CORE */
44#include <iprt/string.h> /* PFNRTSTROUTPUT */
45
46
47RT_C_DECLS_BEGIN
48
49/** @defgroup grp_rt_spc RTCrPem - PEM-file Reader & Writer
50 * @ingroup grp_rt_crypto
51 * @{
52 */
53
54
55/**
56 * One PEM marker word (use RT_STR_TUPLE to initialize).
57 */
58typedef struct RTCRPEMMARKERWORD
59{
60 /** The word string. */
61 const char *pszWord;
62 /** The length. */
63 uint32_t cchWord;
64} RTCRPEMMARKERWORD;
65/** Pointer to a const marker word. */
66typedef RTCRPEMMARKERWORD const *PCRTCRPEMMARKERWORD;
67
68
69/**
70 * A PEM marker.
71 *
72 * This is an array of words with lengths, optimized for avoid unnecessary
73 * strlen() while searching the file content. It is ASSUMED that all PEM
74 * section markers starts with either 'BEGIN' or 'END', followed by the words
75 * in the this structure.
76 */
77typedef struct RTCRPEMMARKER
78{
79 /** Pointer to an array of marker words. */
80 PCRTCRPEMMARKERWORD paWords;
81 /** Number of works in the array papszWords points to. */
82 uint32_t cWords;
83} RTCRPEMMARKER;
84/** Pointer to a const PEM marker. */
85typedef RTCRPEMMARKER const *PCRTCRPEMMARKER;
86
87
88/**
89 * A PEM field.
90 */
91typedef struct RTCRPEMFIELD
92{
93 /** Pointer to the next field. */
94 struct RTCRPEMFIELD const *pNext;
95 /** The field value. */
96 char const *pszValue;
97 /** The field value length. */
98 size_t cchValue;
99 /** The field name length. */
100 size_t cchName;
101 /** The field name. */
102 RT_FLEXIBLE_ARRAY_EXTENSION
103 char szName[RT_FLEXIBLE_ARRAY];
104} RTCRPEMFIELD;
105/** Pointer to a PEM field. */
106typedef RTCRPEMFIELD *PRTCRPEMFIELD;
107/** Pointer to a const PEM field. */
108typedef RTCRPEMFIELD const *PCRTCRPEMFIELD;
109
110
111/**
112 * A PEM section.
113 *
114 * The API works on linked lists of these.
115 */
116typedef struct RTCRPEMSECTION
117{
118 /** Pointer to the next file section. */
119 struct RTCRPEMSECTION const *pNext;
120 /** The marker for this section. NULL if binary file. */
121 PCRTCRPEMMARKER pMarker;
122 /** Pointer to the binary data. */
123 uint8_t *pbData;
124 /** The size of the binary data. */
125 size_t cbData;
126 /** List of fields, NULL if none. */
127 PCRTCRPEMFIELD pFieldHead;
128 /** Set if RTCRPEMREADFILE_F_SENSITIVE was specified. */
129 bool fSensitive;
130} RTCRPEMSECTION;
131/** Pointer to a PEM section. */
132typedef RTCRPEMSECTION *PRTCRPEMSECTION;
133/** Pointer to a const PEM section. */
134typedef RTCRPEMSECTION const *PCRTCRPEMSECTION;
135
136
137/**
138 * Frees sections returned by RTCrPemReadFile and RTCrPemParseContent.
139 * @returns IPRT status code.
140 * @param pSectionHead The first section.
141 */
142RTDECL(int) RTCrPemFreeSections(PCRTCRPEMSECTION pSectionHead);
143
144/**
145 * Parses the given data and returns a list of binary sections.
146 *
147 * If the file isn't an ASCII file or if no markers were found, the entire file
148 * content is returned as one single section (with pMarker = NULL).
149 *
150 * @returns IPRT status code.
151 * @retval VINF_EOF if the file is empty. The @a ppSectionHead value will be
152 * NULL.
153 * @retval VWRN_NOT_FOUND no section was found and RTCRPEMREADFILE_F_ONLY_PEM
154 * is specified. The @a ppSectionHead value will be NULL.
155 *
156 * @param pvContent The content bytes to parse.
157 * @param cbContent The number of content bytes.
158 * @param fFlags RTCRPEMREADFILE_F_XXX.
159 * @param paMarkers Array of one or more section markers to look for.
160 * @param cMarkers Number of markers in the array.
161 * @param ppSectionHead Where to return the head of the section list. Call
162 * RTCrPemFreeSections to free.
163 * @param pErrInfo Where to return extend error info. Optional.
164 */
165RTDECL(int) RTCrPemParseContent(void const *pvContent, size_t cbContent, uint32_t fFlags,
166 PCRTCRPEMMARKER paMarkers, size_t cMarkers, PCRTCRPEMSECTION *ppSectionHead, PRTERRINFO pErrInfo);
167
168/**
169 * Reads the content of the given file and returns a list of binary sections
170 * found in the file.
171 *
172 * If the file isn't an ASCII file or if no markers were found, the entire file
173 * content is returned as one single section (with pMarker = NULL).
174 *
175 * @returns IPRT status code.
176 * @retval VINF_EOF if the file is empty. The @a ppSectionHead value will be
177 * NULL.
178 * @retval VWRN_NOT_FOUND no section was found and RTCRPEMREADFILE_F_ONLY_PEM
179 * is specified. The @a ppSectionHead value will be NULL.
180 *
181 * @param pszFilename The path to the file to read.
182 * @param fFlags RTCRPEMREADFILE_F_XXX.
183 * @param paMarkers Array of one or more section markers to look for.
184 * @param cMarkers Number of markers in the array.
185 * @param ppSectionHead Where to return the head of the section list. Call
186 * RTCrPemFreeSections to free.
187 * @param pErrInfo Where to return extend error info. Optional.
188 */
189RTDECL(int) RTCrPemReadFile(const char *pszFilename, uint32_t fFlags, PCRTCRPEMMARKER paMarkers, size_t cMarkers,
190 PCRTCRPEMSECTION *ppSectionHead, PRTERRINFO pErrInfo);
191/** @name RTCRPEMREADFILE_F_XXX - Flags for RTCrPemReadFile and
192 * RTCrPemParseContent.
193 * @{ */
194/** Continue on encoding error. */
195#define RTCRPEMREADFILE_F_CONTINUE_ON_ENCODING_ERROR RT_BIT(0)
196/** Only PEM sections, no binary fallback. */
197#define RTCRPEMREADFILE_F_ONLY_PEM RT_BIT(1)
198/** Sensitive data, use the safer allocator. */
199#define RTCRPEMREADFILE_F_SENSITIVE RT_BIT(2)
200/** Valid flags. */
201#define RTCRPEMREADFILE_F_VALID_MASK UINT32_C(0x00000007)
202/** @} */
203
204/**
205 * Finds the beginning of first PEM section using the specified markers.
206 *
207 * This will not look any further than the first section. Nor will it check for
208 * binaries.
209 *
210 * @returns Pointer to the "-----BEGIN XXXX" sequence on success.
211 * NULL if not found.
212 * @param pvContent The content bytes to parse.
213 * @param cbContent The number of content bytes.
214 * @param paMarkers Array of one or more section markers to look for.
215 * @param cMarkers Number of markers in the array.
216 */
217RTDECL(const char *) RTCrPemFindFirstSectionInContent(void const *pvContent, size_t cbContent,
218 PCRTCRPEMMARKER paMarkers, size_t cMarkers);
219
220
221/**
222 * PEM formatter for a binary data blob.
223 *
224 * @returns Number of output bytes (sum of @a pfnOutput return values).
225 * @param pfnOutput The output callback function.
226 * @param pvUser The user argument to the output callback.
227 * @param pvContent The binary blob to output.
228 * @param cbContent Size of the binary blob.
229 * @param pszMarker The PEM marker, .e.g "PRIVATE KEY", "CERTIFICATE" or
230 * similar.
231 * @sa RTCrPemWriteAsn1, RTCrPemWriteAsn1ToVfsFile,
232 * RTCrPemWriteAsn1ToVfsFile
233 */
234RTDECL(size_t) RTCrPemWriteBlob(PFNRTSTROUTPUT pfnOutput, void *pvUser,
235 const void *pvContent, size_t cbContent, const char *pszMarker);
236
237RTDECL(ssize_t) RTCrPemWriteBlobToVfsIoStrm(RTVFSIOSTREAM hVfsIos, const void *pvContent, size_t cbContent, const char *pszMarker);
238RTDECL(ssize_t) RTCrPemWriteBlobToVfsFile(RTVFSFILE hVfsFile, const void *pvContent, size_t cbContent, const char *pszMarker);
239
240/**
241 * PEM formatter for a generic ASN.1 structure.
242 *
243 * This will call both RTAsn1EncodePrepare() and RTAsn1EncodeWrite() on
244 * @a pRoot. Uses DER encoding.
245 *
246 * @returns Number of outputted chars (sum of @a pfnOutput return values),
247 * negative values are error status codes from the ASN.1 encoding.
248 * @param pfnOutput The output callback function.
249 * @param pvUser The user argument to the output callback.
250 * @param fFlags Reserved, MBZ.
251 * @param pRoot The root of the ASN.1 to encode and format as PEM.
252 * @param pszMarker The PEM marker, .e.g "PRIVATE KEY", "CERTIFICATE" or
253 * similar.
254 * @param pErrInfo For encoding errors. Optional.
255 * @sa RTCrPemWriteAsn1ToVfsFile, RTCrPemWriteAsn1ToVfsFile,
256 * RTCrPemWriteBlob
257 */
258RTDECL(ssize_t) RTCrPemWriteAsn1(PFNRTSTROUTPUT pfnOutput, void *pvUser, PRTASN1CORE pRoot,
259 uint32_t fFlags, const char *pszMarker, PRTERRINFO pErrInfo);
260
261/**
262 * PEM formatter for a generic ASN.1 structure and output it to @a hVfsIos.
263 *
264 * This will call both RTAsn1EncodePrepare() and RTAsn1EncodeWrite() on
265 * @a pRoot. Uses DER encoding.
266 *
267 * @returns Number of chars written, negative values are error status codes from
268 * the ASN.1 encoding or from RTVfsIoStrmWrite().
269 * @param hVfsIos Handle to the I/O stream to write it to.
270 * @param fFlags Reserved, MBZ.
271 * @param pRoot The root of the ASN.1 to encode and format as PEM.
272 * @param pszMarker The PEM marker, .e.g "PRIVATE KEY", "CERTIFICATE" or
273 * similar.
274 * @param pErrInfo For encoding errors. Optional.
275 * @sa RTCrPemWriteAsn1ToVfsFile, RTCrPemWriteAsn1, RTCrPemWriteBlob
276 */
277RTDECL(ssize_t) RTCrPemWriteAsn1ToVfsIoStrm(RTVFSIOSTREAM hVfsIos, PRTASN1CORE pRoot,
278 uint32_t fFlags, const char *pszMarker, PRTERRINFO pErrInfo);
279
280/**
281 * PEM formatter for a generic ASN.1 structure and output it to @a hVfsFile.
282 *
283 * This will call both RTAsn1EncodePrepare() and RTAsn1EncodeWrite() on
284 * @a pRoot. Uses DER encoding.
285 *
286 * @returns Number of chars written, negative values are error status codes from
287 * the ASN.1 encoding or from RTVfsIoStrmWrite().
288 * @param hVfsFile Handle to the file to write it to.
289 * @param fFlags Reserved, MBZ.
290 * @param pRoot The root of the ASN.1 to encode and format as PEM.
291 * @param pszMarker The PEM marker, .e.g "PRIVATE KEY", "CERTIFICATE" or
292 * similar.
293 * @param pErrInfo For encoding errors. Optional.
294 * @sa RTCrPemWriteAsn1ToVfsIoStrm, RTCrPemWriteAsn1, RTCrPemWriteBlob
295 */
296RTDECL(ssize_t) RTCrPemWriteAsn1ToVfsFile(RTVFSFILE hVfsFile, PRTASN1CORE pRoot,
297 uint32_t fFlags, const char *pszMarker, PRTERRINFO pErrInfo);
298
299/** @} */
300
301RT_C_DECLS_END
302
303#endif /* !IPRT_INCLUDED_crypto_pem_h */
304
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use