VirtualBox

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

最後變更 在這個檔案從100421是 100421,由 vboxsync 提交於 21 月 前

IPRT/PKCS8: add key format for PKCS #8 bugref:10299

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

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