VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/crypto/key-file.cpp@ 84204

Last change on this file since 84204 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.6 KB
Line 
1/* $Id: key-file.cpp 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * IPRT - Crypto - Cryptographic Keys, File I/O.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include "internal/iprt.h"
32#include <iprt/crypto/key.h>
33
34#include <iprt/alloca.h>
35#include <iprt/asm.h>
36#include <iprt/assert.h>
37#include <iprt/ctype.h>
38#include <iprt/err.h>
39#include <iprt/mem.h>
40#include <iprt/memsafer.h>
41#include <iprt/path.h>
42#include <iprt/string.h>
43#include <iprt/crypto/rsa.h>
44#include <iprt/crypto/pkix.h>
45#include <iprt/crypto/x509.h>
46
47#include "internal/magics.h"
48#include "key-internal.h"
49
50#ifdef IPRT_WITH_OPENSSL
51# include "internal/iprt-openssl.h"
52# include "openssl/evp.h"
53# ifndef OPENSSL_VERSION_NUMBER
54# error "Missing OPENSSL_VERSION_NUMBER!"
55# endif
56#endif
57
58
59/*********************************************************************************************************************************
60* Header Files *
61*********************************************************************************************************************************/
62/** RSA public key marker words. */
63static RTCRPEMMARKERWORD const g_aWords_RsaPublicKey[] =
64{ { RT_STR_TUPLE("RSA") }, { RT_STR_TUPLE("PUBLIC") }, { RT_STR_TUPLE("KEY") } };
65/** Generic public key marker words. */
66static RTCRPEMMARKERWORD const g_aWords_PublicKey[] =
67{ { RT_STR_TUPLE("PUBLIC") }, { RT_STR_TUPLE("KEY") } };
68
69/** Public key markers. */
70RT_DECL_DATA_CONST(RTCRPEMMARKER const) g_aRTCrKeyPublicMarkers[] =
71{
72 { g_aWords_RsaPublicKey, RT_ELEMENTS(g_aWords_RsaPublicKey) },
73 { g_aWords_PublicKey, RT_ELEMENTS(g_aWords_PublicKey) },
74};
75/** Number of entries in g_aRTCrKeyPublicMarkers. */
76RT_DECL_DATA_CONST(uint32_t const) g_cRTCrKeyPublicMarkers = RT_ELEMENTS(g_aRTCrKeyPublicMarkers);
77
78
79/** RSA private key marker words. */
80static RTCRPEMMARKERWORD const g_aWords_RsaPrivateKey[] =
81{ { RT_STR_TUPLE("RSA") }, { RT_STR_TUPLE("PRIVATE") }, { RT_STR_TUPLE("KEY") } };
82/** Generic encrypted private key marker words. */
83static RTCRPEMMARKERWORD const g_aWords_EncryptedPrivateKey[] =
84{ { RT_STR_TUPLE("ENCRYPTED") }, { RT_STR_TUPLE("PRIVATE") }, { RT_STR_TUPLE("KEY") } };
85/** Generic private key marker words. */
86static RTCRPEMMARKERWORD const g_aWords_PrivateKey[] =
87{ { RT_STR_TUPLE("PRIVATE") }, { RT_STR_TUPLE("KEY") } };
88
89/** Private key markers. */
90RT_DECL_DATA_CONST(RTCRPEMMARKER const) g_aRTCrKeyPrivateMarkers[] =
91{
92 { g_aWords_RsaPrivateKey, RT_ELEMENTS(g_aWords_RsaPrivateKey) },
93 { g_aWords_EncryptedPrivateKey, RT_ELEMENTS(g_aWords_EncryptedPrivateKey) },
94 { g_aWords_PrivateKey, RT_ELEMENTS(g_aWords_PrivateKey) },
95};
96/** Number of entries in g_aRTCrKeyPrivateMarkers. */
97RT_DECL_DATA_CONST(uint32_t const) g_cRTCrKeyPrivateMarkers = RT_ELEMENTS(g_aRTCrKeyPrivateMarkers);
98
99
100/** Private and public key markers. */
101RT_DECL_DATA_CONST(RTCRPEMMARKER const) g_aRTCrKeyAllMarkers[] =
102{
103 { g_aWords_RsaPublicKey, RT_ELEMENTS(g_aWords_RsaPublicKey) },
104 { g_aWords_PublicKey, RT_ELEMENTS(g_aWords_PublicKey) },
105 { g_aWords_RsaPrivateKey, RT_ELEMENTS(g_aWords_RsaPrivateKey) },
106 { g_aWords_PrivateKey, RT_ELEMENTS(g_aWords_PrivateKey) },
107};
108/** Number of entries in g_aRTCrKeyAllMarkers. */
109RT_DECL_DATA_CONST(uint32_t const) g_cRTCrKeyAllMarkers = RT_ELEMENTS(g_aRTCrKeyAllMarkers);
110
111
112/**
113 * Decrypts a PEM message.
114 *
115 * @returns IPRT status code
116 * @param pszDekInfo The decryption info. See RFC-1421 section 4.6.1.3
117 * as well as RFC-1423).
118 * @param pszPassword The password to use to decrypt the key text.
119 * @param pbEncrypted The encrypted key text.
120 * @param cbEncrypted The size of the encrypted text.
121 * @param ppbDecrypted Where to return the decrypted message. Free using RTMemSaferFree.
122 * @param pcbDecrypted Where to return the length of the decrypted message.
123 * @param pcbDecryptedAlloced Where to return the allocation size.
124 * @param pErrInfo Where to return additional error information.
125 */
126static int rtCrKeyDecryptPemMessage(const char *pszDekInfo, const char *pszPassword, uint8_t *pbEncrypted, size_t cbEncrypted,
127 uint8_t **ppbDecrypted, size_t *pcbDecrypted, size_t *pcbDecryptedAlloced, PRTERRINFO pErrInfo)
128{
129 /*
130 * Initialize return values.
131 */
132 *ppbDecrypted = NULL;
133 *pcbDecrypted = 0;
134 *pcbDecryptedAlloced = 0;
135
136 /*
137 * Parse the DEK-Info.
138 */
139 if (!pszDekInfo)
140 return VERR_CR_KEY_NO_DEK_INFO;
141
142 /* Find the end of the algorithm */
143 const char *pszParams = strchr(pszDekInfo, ',');
144 if (!pszParams)
145 pszParams = strchr(pszDekInfo, '\0');
146 size_t cchAlgo = pszParams - pszDekInfo;
147 while (cchAlgo > 0 && RT_C_IS_SPACE(pszDekInfo[cchAlgo - 1]))
148 cchAlgo--;
149
150 /* Copy it out and zero terminating it. */
151 char szAlgo[256];
152 if (cchAlgo >= sizeof(szAlgo))
153 return RTErrInfoSetF(pErrInfo, VERR_CR_KEY_DEK_INFO_TOO_LONG, "Algorithms list is too long (%s)", pszDekInfo);
154 memcpy(szAlgo, pszDekInfo, cchAlgo);
155 szAlgo[cchAlgo] = '\0';
156
157 /* Parameters. */
158 pszParams = RTStrStripL(*pszParams == ',' ? pszParams + 1 : pszParams);
159 size_t const cchParams = strlen(pszParams);
160
161 /*
162 * Do we support the cihper?
163 */
164#ifdef IPRT_WITH_OPENSSL /** @todo abstract encryption & decryption. */
165 const EVP_CIPHER *pCipher = EVP_get_cipherbyname(szAlgo);
166 if (!pCipher)
167 return RTErrInfoSetF(pErrInfo, VERR_CR_KEY_UNSUPPORTED_CIPHER, "Unknown key cipher: %s (params: %s)", szAlgo, pszParams);
168
169 /* Decode the initialization vector if one is required. */
170 uint8_t *pbInitVector = NULL;
171 int const cbInitVector = EVP_CIPHER_iv_length(pCipher);
172 if (cbInitVector > 0)
173 {
174 if (*pszParams == '\0')
175 return RTErrInfoSetF(pErrInfo, VERR_CR_KEY_MISSING_CIPHER_PARAMS,
176 "Cipher '%s' expected %u bytes initialization vector, none found", cbInitVector, szAlgo);
177 if ((size_t)cbInitVector > cchParams / 2)
178 return RTErrInfoSetF(pErrInfo, VERR_CR_KEY_TOO_SHORT_CIPHER_IV,
179 "Too short initialization vector for '%s', expected %u chars found only %u: %s",
180 szAlgo, cbInitVector * 2, cchParams, pszParams);
181 pbInitVector = (uint8_t *)alloca(cbInitVector);
182 int rc = RTStrConvertHexBytes(pszParams, pbInitVector, cbInitVector, 0 /*fFlags*/);
183 if ( RT_FAILURE(rc)
184 && rc != VERR_BUFFER_OVERFLOW /* openssl ignores this condition */)
185 return RTErrInfoSetF(pErrInfo, VERR_CR_KEY_MALFORMED_CIPHER_IV,
186 "Malformed initialization vector for '%s': %s (rc=%Rrc)", szAlgo, pszParams, rc);
187 }
188 else if (*pszParams != '\0')
189 return RTErrInfoSetF(pErrInfo, VERR_CR_KEY_UNEXPECTED_CIPHER_PARAMS,
190 "Cipher '%s' expected no parameters, found: %s", szAlgo, pszParams);
191
192 /*
193 * Do we have a password? If so try decrypt the key.
194 */
195 if (!pszPassword)
196 return VERR_CR_KEY_ENCRYPTED;
197
198 unsigned char abKey[EVP_MAX_KEY_LENGTH * 2];
199 int cbKey = EVP_BytesToKey(pCipher, EVP_md5(), pbInitVector, (unsigned char const *)pszPassword, (int)strlen(pszPassword),
200 1, abKey, NULL);
201 if (!cbKey)
202 return RTErrInfoSetF(pErrInfo, VERR_CR_KEY_PASSWORD_ENCODING, "EVP_BytesToKey failed to encode password");
203
204 EVP_CIPHER_CTX *pCipherCtx = EVP_CIPHER_CTX_new();
205 if (!pCipherCtx)
206 return VERR_NO_MEMORY;
207
208 int rc;
209 if (EVP_DecryptInit_ex(pCipherCtx, pCipher, NULL /*pEngine*/, abKey, pbInitVector))
210 {
211 size_t cbDecryptedAlloced = cbEncrypted;
212 int cbDecrypted = (int)cbDecryptedAlloced;
213 uint8_t *pbDecrypted = (uint8_t *)RTMemSaferAllocZ(cbDecryptedAlloced);
214 if (pbDecrypted)
215 {
216 if (EVP_DecryptUpdate(pCipherCtx, pbDecrypted, &cbDecrypted, pbEncrypted, (int)cbEncrypted))
217 {
218 int cbFinal = (int)cbDecryptedAlloced - cbDecrypted;
219 if (EVP_DecryptFinal_ex(pCipherCtx, &pbDecrypted[cbDecrypted], &cbFinal))
220 {
221 cbDecrypted += cbFinal;
222 Assert((size_t)cbDecrypted <= cbDecryptedAlloced);
223
224 /*
225 * Done! Just set the return values.
226 */
227 *pcbDecrypted = cbDecrypted;
228 *pcbDecryptedAlloced = cbDecryptedAlloced;
229 *ppbDecrypted = pbDecrypted;
230 pbDecrypted = NULL;
231 rc = VINF_CR_KEY_WAS_DECRYPTED;
232 }
233 else
234 rc = RTErrInfoSetF(pErrInfo, VERR_CR_KEY_DECRYPTION_FAILED,
235 "Incorrect password? EVP_DecryptFinal_ex failed for %s", pszDekInfo);
236 }
237 else
238 rc = RTErrInfoSetF(pErrInfo, VERR_CR_KEY_DECRYPTION_FAILED,
239 "Incorrect password? EVP_DecryptUpdate failed for %s", pszDekInfo);
240 if (pbDecrypted)
241 RTMemSaferFree(pbDecrypted, cbDecryptedAlloced);
242 }
243 else
244 rc = VERR_NO_MEMORY;
245 }
246 else
247 rc = RTErrInfoSetF(pErrInfo, VERR_CR_KEY_OSSL_DECRYPT_INIT_ERROR, "EVP_DecryptInit_ex failed for %s", pszDekInfo);
248 EVP_CIPHER_CTX_free(pCipherCtx);
249 return rc;
250#else
251 RT_NOREF(pbEncrypted, cbEncrypted, pszPassword, pErrInfo, cchParams);
252 return VERR_CR_KEY_DECRYPTION_NOT_SUPPORTED;
253#endif
254}
255
256
257RTDECL(int) RTCrKeyCreateFromPemSection(PRTCRKEY phKey, PCRTCRPEMSECTION pSection, uint32_t fFlags, const char *pszPassword,
258 PRTERRINFO pErrInfo, const char *pszErrorTag)
259{
260 AssertReturn(!(fFlags & (~RTCRKEYFROM_F_VALID_MASK | RTCRKEYFROM_F_ONLY_PEM)), VERR_INVALID_FLAGS);
261
262 AssertPtrReturn(phKey, VERR_INVALID_POINTER);
263 *phKey = NIL_RTCRKEY;
264 AssertPtrReturn(pSection, VERR_INVALID_POINTER);
265 NOREF(pszPassword);
266
267 /*
268 * If the source is PEM section, try identify the format from the markers.
269 */
270 enum
271 {
272 kKeyFormat_Unknown = 0,
273 kKeyFormat_RsaPrivateKey,
274 kKeyFormat_RsaEncryptedPrivateKey,
275 kKeyFormat_RsaPublicKey,
276 kKeyFormat_SubjectPublicKeyInfo,
277 kKeyFormat_PrivateKeyInfo,
278 kKeyFormat_EncryptedPrivateKeyInfo
279 } enmFormat = kKeyFormat_Unknown;
280 const char *pszDekInfo = NULL;
281 PCRTCRPEMMARKER pMarker = pSection->pMarker;
282 if (pMarker)
283 {
284 if ( pMarker->cWords == 3
285 && strcmp(pMarker->paWords[0].pszWord, "RSA") == 0
286 && strcmp(pMarker->paWords[2].pszWord, "KEY") == 0)
287 {
288 if (strcmp(pMarker->paWords[1].pszWord, "PUBLIC") == 0)
289 enmFormat = kKeyFormat_RsaPublicKey;
290 else if (strcmp(pMarker->paWords[1].pszWord, "PRIVATE") == 0)
291 {
292 enmFormat = kKeyFormat_RsaPrivateKey;
293
294 /* RSA PRIVATE KEY encryption is advertised thru PEM header fields.
295 We need the DEK field to decrypt the message (see RFC-1421 4.6.1.3). */
296 for (PCRTCRPEMFIELD pField = pSection->pFieldHead; pField; pField = pField->pNext)
297 {
298 if ( pField->cchName == sizeof("Proc-Type") - 1
299 && pField->cchValue >= sizeof("4,ENCRYPTED") - 1
300 && memcmp(pField->szName, RT_STR_TUPLE("Proc-Type")) == 0)
301 {
302 const char *pszValue = pField->pszValue;
303 if (*pszValue == '4')
304 {
305 do
306 pszValue++;
307 while (RT_C_IS_SPACE(*pszValue) || RT_C_IS_PUNCT(*pszValue));
308 if (strcmp(pszValue, "ENCRYPTED") == 0)
309 enmFormat = kKeyFormat_RsaEncryptedPrivateKey;
310 }
311 }
312 else if ( pField->cchName == sizeof("DEK-Info") - 1
313 && pField->cchValue > 0
314 && !pszDekInfo)
315 pszDekInfo = pField->pszValue;
316 }
317 }
318 else
319 AssertFailed();
320 }
321 else if ( pMarker->cWords == 2
322 && strcmp(pMarker->paWords[1].pszWord, "KEY") == 0)
323 {
324 if (strcmp(pMarker->paWords[0].pszWord, "PUBLIC") == 0)
325 enmFormat = kKeyFormat_SubjectPublicKeyInfo;
326 else if (strcmp(pMarker->paWords[0].pszWord, "PRIVATE") == 0)
327 enmFormat = kKeyFormat_PrivateKeyInfo;
328 else
329 AssertFailed();
330 }
331 else if ( pMarker->cWords == 3
332 && strcmp(pMarker->paWords[0].pszWord, "ENCRYPTED") == 0
333 && strcmp(pMarker->paWords[1].pszWord, "PRIVATE") == 0
334 && strcmp(pMarker->paWords[2].pszWord, "KEY") == 0)
335 enmFormat = kKeyFormat_EncryptedPrivateKeyInfo;
336 else
337 AssertFailed();
338 }
339
340 /*
341 * Try guess the format from the binary data if needed.
342 */
343 RTASN1CURSORPRIMARY PrimaryCursor;
344 if ( enmFormat == kKeyFormat_Unknown
345 && pSection->cbData > 10)
346 {
347 RTAsn1CursorInitPrimary(&PrimaryCursor, pSection->pbData, (uint32_t)pSection->cbData,
348 pErrInfo, &g_RTAsn1DefaultAllocator, RTASN1CURSOR_FLAGS_DER, "probing/0");
349
350 /*
351 * First the must be a sequence.
352 */
353 RTASN1CORE Tag;
354 int rc = RTAsn1CursorReadHdr(&PrimaryCursor.Cursor, &Tag, "#1");
355 if (RT_SUCCESS(rc) && Tag.uTag == ASN1_TAG_SEQUENCE)
356 {
357 RTASN1CURSOR Cursor2;
358 RTAsn1CursorInitSubFromCore(&PrimaryCursor.Cursor, &Tag, &Cursor2, "probing/1");
359 rc = RTAsn1CursorReadHdr(&Cursor2, &Tag, "#2");
360
361 /*
362 * SEQUENCE SubjectPublicKeyInfo.Algorithm?
363 */
364 if (RT_SUCCESS(rc) && Tag.uTag == ASN1_TAG_SEQUENCE)
365 {
366 RTASN1CURSOR Cursor3;
367 RTAsn1CursorInitSubFromCore(&Cursor2, &Tag, &Cursor3, "probing/2");
368 rc = RTAsn1CursorReadHdr(&Cursor3, &Tag, "#3");
369
370 /* SEQUENCE SubjectPublicKeyInfo.Algorithm.Algorithm? */
371 if (RT_SUCCESS(rc) && Tag.uTag == ASN1_TAG_OID)
372 enmFormat = kKeyFormat_SubjectPublicKeyInfo;
373 }
374 /*
375 * INTEGER PrivateKeyInfo.Version?
376 * INTEGER RsaPublicKey.Modulus?
377 * INTEGER RsaPrivateKey.Version?
378 */
379 else if (RT_SUCCESS(rc) && Tag.uTag == ASN1_TAG_INTEGER)
380 {
381 rc = RTAsn1CursorReadHdr(RTAsn1CursorSkip(&Cursor2, Tag.cb), &Tag, "#4");
382
383 /* OBJECT PrivateKeyInfo.privateKeyAlgorithm? */
384 if (RT_SUCCESS(rc) && Tag.uTag == ASN1_TAG_OID)
385 enmFormat = kKeyFormat_PrivateKeyInfo;
386 /* INTEGER RsaPublicKey.PublicExponent?
387 INTEGER RsaPrivateKey.Modulus? */
388 else if (RT_SUCCESS(rc) && Tag.uTag == ASN1_TAG_INTEGER)
389 {
390 /* RsaPublicKey.PublicExponent is at the end. */
391 if (RTAsn1CursorIsEnd(&Cursor2))
392 enmFormat = kKeyFormat_RsaPublicKey;
393 else
394 {
395 /* Check for INTEGER RsaPrivateKey.PublicExponent nad PrivateExponent before concluding. */
396 rc = RTAsn1CursorReadHdr(RTAsn1CursorSkip(&Cursor2, Tag.cb), &Tag, "#5");
397 if (RT_SUCCESS(rc) && Tag.uTag == ASN1_TAG_INTEGER)
398 {
399 rc = RTAsn1CursorReadHdr(RTAsn1CursorSkip(&Cursor2, Tag.cb), &Tag, "#6");
400 if (RT_SUCCESS(rc) && Tag.uTag == ASN1_TAG_INTEGER)
401 enmFormat = kKeyFormat_RsaPrivateKey;
402 }
403 }
404 }
405 }
406 }
407 }
408
409 if (enmFormat == kKeyFormat_Unknown)
410 return RTErrInfoSetF(pErrInfo, VERR_CR_KEY_UNKNOWN_TYPE,
411 "Unable to identify the key format (%.*Rhxs)", RT_MIN(16, pSection->cbData), pSection->pbData);
412
413 /*
414 * Do the reading.
415 */
416 int rc;
417 switch (enmFormat)
418 {
419 case kKeyFormat_RsaPublicKey:
420 rc = rtCrKeyCreateRsaPublic(phKey, pSection->pbData, (uint32_t)pSection->cbData, pErrInfo, pszErrorTag);
421 break;
422
423 case kKeyFormat_RsaPrivateKey:
424 rc = rtCrKeyCreateRsaPrivate(phKey, pSection->pbData, (uint32_t)pSection->cbData, pErrInfo, pszErrorTag);
425 break;
426
427 case kKeyFormat_RsaEncryptedPrivateKey:
428 {
429 uint8_t *pbDecrypted = NULL;
430 size_t cbDecrypted = 0;
431 size_t cbDecryptedAlloced = 0;
432 rc = rtCrKeyDecryptPemMessage(pszDekInfo, pszPassword, pSection->pbData, pSection->cbData,
433 &pbDecrypted, &cbDecrypted, &cbDecryptedAlloced, pErrInfo);
434 if (RT_SUCCESS(rc))
435 {
436 int rc2 = rtCrKeyCreateRsaPrivate(phKey, pbDecrypted, (uint32_t)cbDecrypted, pErrInfo, pszErrorTag);
437 if (rc2 != VINF_SUCCESS)
438 rc = rc2;
439 RTMemSaferFree(pbDecrypted, cbDecryptedAlloced);
440 }
441 break;
442 }
443
444 case kKeyFormat_SubjectPublicKeyInfo:
445 {
446 RTAsn1CursorInitPrimary(&PrimaryCursor, pSection->pbData, (uint32_t)pSection->cbData,
447 pErrInfo, &g_RTAsn1DefaultAllocator, RTASN1CURSOR_FLAGS_DER, pszErrorTag);
448 RTCRX509SUBJECTPUBLICKEYINFO SubjectPubKeyInfo;
449 RT_ZERO(SubjectPubKeyInfo);
450 rc = RTCrX509SubjectPublicKeyInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &SubjectPubKeyInfo, "SubjectPubKeyInfo");
451 if (RT_SUCCESS(rc))
452 {
453 rc = RTCrKeyCreateFromSubjectPublicKeyInfo(phKey, &SubjectPubKeyInfo, pErrInfo, pszErrorTag);
454 RTCrX509SubjectPublicKeyInfo_Delete(&SubjectPubKeyInfo);
455 }
456 break;
457 }
458
459 case kKeyFormat_PrivateKeyInfo:
460 rc = RTErrInfoSet(pErrInfo, VERR_CR_KEY_FORMAT_NOT_SUPPORTED,
461 "Support for PKCS#8 PrivateKeyInfo is not yet implemented");
462 break;
463
464 case kKeyFormat_EncryptedPrivateKeyInfo:
465 rc = RTErrInfoSet(pErrInfo, VERR_CR_KEY_FORMAT_NOT_SUPPORTED,
466 "Support for encrypted PKCS#8 PrivateKeyInfo is not yet implemented");
467 break;
468
469 default:
470 AssertFailedStmt(rc = VERR_INTERNAL_ERROR_4);
471 }
472 return rc;
473}
474
475
476RTDECL(int) RTCrKeyCreateFromBuffer(PRTCRKEY phKey, uint32_t fFlags, void const *pvSrc, size_t cbSrc, const char *pszPassword,
477 PRTERRINFO pErrInfo, const char *pszErrorTag)
478{
479 AssertReturn(!(fFlags & ~RTCRKEYFROM_F_VALID_MASK), VERR_INVALID_FLAGS);
480 PCRTCRPEMSECTION pSectionHead;
481 int rc = RTCrPemParseContent(pvSrc, cbSrc, fFlags, g_aRTCrKeyAllMarkers, g_cRTCrKeyAllMarkers, &pSectionHead, pErrInfo);
482 if (RT_SUCCESS(rc))
483 {
484 if (pSectionHead)
485 {
486 rc = RTCrKeyCreateFromPemSection(phKey, pSectionHead, fFlags & ~RTCRKEYFROM_F_ONLY_PEM, pszPassword,
487 pErrInfo, pszErrorTag);
488 RTCrPemFreeSections(pSectionHead);
489 }
490 else
491 rc = rc != VINF_SUCCESS ? -rc : VERR_INTERNAL_ERROR_2;
492 }
493 return rc;
494}
495
496
497RTDECL(int) RTCrKeyCreateFromFile(PRTCRKEY phKey, uint32_t fFlags, const char *pszFilename,
498 const char *pszPassword, PRTERRINFO pErrInfo)
499{
500 AssertReturn(!(fFlags & ~RTCRKEYFROM_F_VALID_MASK), VERR_INVALID_FLAGS);
501 PCRTCRPEMSECTION pSectionHead;
502 int rc = RTCrPemReadFile(pszFilename, fFlags, g_aRTCrKeyAllMarkers, g_cRTCrKeyAllMarkers, &pSectionHead, pErrInfo);
503 if (RT_SUCCESS(rc))
504 {
505 if (pSectionHead)
506 {
507 rc = RTCrKeyCreateFromPemSection(phKey, pSectionHead, fFlags & ~RTCRKEYFROM_F_ONLY_PEM, pszPassword,
508 pErrInfo, RTPathFilename(pszFilename));
509 RTCrPemFreeSections(pSectionHead);
510 }
511 else
512 rc = rc != VINF_SUCCESS ? -rc : VERR_INTERNAL_ERROR_2;
513 }
514 return rc;
515}
516
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette