Changeset 100528 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Jul 11, 2023 10:52:34 PM (17 months ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/crypto/key-file.cpp
r100494 r100528 39 39 * Header Files * 40 40 *********************************************************************************************************************************/ 41 #define LOG_GROUP RTLOGGROUP_CRYPTO 41 42 #include "internal/iprt.h" 42 43 #include <iprt/crypto/key.h> … … 47 48 #include <iprt/ctype.h> 48 49 #include <iprt/err.h> 50 #include <iprt/log.h> 49 51 #include <iprt/mem.h> 50 52 #include <iprt/memsafer.h> … … 62 64 # include "internal/iprt-openssl.h" 63 65 # include "internal/openssl-pre.h" 66 # include <openssl/err.h> 64 67 # include <openssl/evp.h> 68 # include <openssl/pkcs12.h> 65 69 # include "internal/openssl-post.h" 66 70 # ifndef OPENSSL_VERSION_NUMBER … … 114 118 RT_DECL_DATA_CONST(RTCRPEMMARKER const) g_aRTCrKeyAllMarkers[] = 115 119 { 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 { g_aWords_RsaPublicKey, RT_ELEMENTS(g_aWords_RsaPublicKey) }, 121 { g_aWords_PublicKey, RT_ELEMENTS(g_aWords_PublicKey) }, 122 { g_aWords_RsaPrivateKey, RT_ELEMENTS(g_aWords_RsaPrivateKey) }, 123 { g_aWords_EncryptedPrivateKey, RT_ELEMENTS(g_aWords_EncryptedPrivateKey) }, 124 { g_aWords_PrivateKey, RT_ELEMENTS(g_aWords_PrivateKey) }, 120 125 }; 121 126 /** Number of entries in g_aRTCrKeyAllMarkers. */ 122 127 RT_DECL_DATA_CONST(uint32_t const) g_cRTCrKeyAllMarkers = RT_ELEMENTS(g_aRTCrKeyAllMarkers); 128 129 130 /** 131 * Creates a key from a raw PKCS\#8 PrivateKeyInfo structure. 132 * 133 * This is common code to both kKeyFormat_PrivateKeyInfo and 134 * kKeyFormat_EncryptedPrivateKeyInfo. 135 * 136 * @returns IPRT status code. 137 * @param phKey Where to return the key handle on success. 138 * @param pPrimaryCursor Cursor structure to use. 139 * @param pbRaw The raw PrivateKeyInfo bytes. 140 * @param cbRaw Size of the raw PrivateKeyInfo structure. 141 * @param pErrInfo Where to return additional error information. 142 * @param pszErrorTag What to tag the decoding with. 143 */ 144 static int rtCrKeyCreateFromPrivateKeyInfo(PRTCRKEY phKey, PRTASN1CURSORPRIMARY pPrimaryCursor, 145 uint8_t const *pbRaw, size_t cbRaw, PRTERRINFO pErrInfo, const char *pszErrorTag) 146 147 { 148 RTCRPKCS8PRIVATEKEYINFO PrivateKeyInfo; 149 RT_ZERO(PrivateKeyInfo); 150 RTAsn1CursorInitPrimary(pPrimaryCursor, pbRaw, (uint32_t)cbRaw, pErrInfo, &g_RTAsn1DefaultAllocator, 151 RTASN1CURSOR_FLAGS_DER, pszErrorTag); 152 int rc = RTCrPkcs8PrivateKeyInfo_DecodeAsn1(&pPrimaryCursor->Cursor, 0, &PrivateKeyInfo, 153 pszErrorTag ? pszErrorTag : "PrivateKeyInfo"); 154 if (RT_SUCCESS(rc)) 155 { 156 /* 157 * Load the private key according to it's algorithm. 158 * We currently only support RSA (pkcs1-RsaEncryption). 159 */ 160 if (RTAsn1ObjId_CompareWithString(&PrivateKeyInfo.PrivateKeyAlgorithm.Algorithm, RTCRX509ALGORITHMIDENTIFIERID_RSA) == 0) 161 rc = rtCrKeyCreateRsaPrivate(phKey, PrivateKeyInfo.PrivateKey.Asn1Core.uData.pv, 162 PrivateKeyInfo.PrivateKey.Asn1Core.cb, pErrInfo, pszErrorTag); 163 else 164 rc = RTERRINFO_LOG_SET(pErrInfo, VERR_CR_KEY_FORMAT_NOT_SUPPORTED, 165 "Support for PKCS#8 PrivateKeyInfo for non-RSA keys is not yet implemented"); 166 RTCrPkcs8PrivateKeyInfo_Delete(&PrivateKeyInfo); 167 } 168 return rc; 169 } 170 171 172 /** 173 * Decrypts a PEM message. 174 * 175 * @returns IPRT status code 176 * @param pEncryptedKey The encrypted private key information. 177 * @param pszPassword The password to use to decrypt the key text. 178 * @param ppbDecrypted Where to return the decrypted message. Free using RTMemSaferFree. 179 * @param pcbDecrypted Where to return the length of the decrypted message. 180 * @param pcbDecryptedAlloced Where to return the allocation size. 181 * @param pErrInfo Where to return additional error information. 182 */ 183 static int rtCrKeyDecryptPkcs8Info(PRTCRPKCS8ENCRYPTEDPRIVATEKEYINFO pEncryptedKey, const char *pszPassword, 184 uint8_t **ppbDecrypted, size_t *pcbDecrypted, size_t *pcbDecryptedAlloced, PRTERRINFO pErrInfo) 185 { 186 /* 187 * Initialize return values. 188 */ 189 *ppbDecrypted = NULL; 190 *pcbDecrypted = 0; 191 *pcbDecryptedAlloced = 0; 192 193 /* 194 * This operation requires a password. 195 */ 196 if (!pszPassword) 197 return VERR_CR_KEY_ENCRYPTED; 198 199 #ifdef IPRT_WITH_OPENSSL /** @todo abstract encryption & decryption. */ 200 201 /* 202 * Query the EncryptionAlgorithm bytes so we can construction a X509_ALGOR 203 * for use in PKCS12_pbe_crypt. 204 */ 205 void *pvAlgoFree = NULL; 206 const uint8_t *pbAlgoRaw = NULL; 207 uint32_t cbAlgoRaw = 0; 208 int rc = RTAsn1EncodeQueryRawBits(&pEncryptedKey->EncryptionAlgorithm.SeqCore.Asn1Core, 209 &pbAlgoRaw, &cbAlgoRaw, &pvAlgoFree, pErrInfo); 210 AssertRCReturn(rc, rc); 211 212 const unsigned char *puchAlgo = pbAlgoRaw; 213 X509_ALGOR *pOsslAlgoRet = NULL; 214 pOsslAlgoRet = d2i_X509_ALGOR(&pOsslAlgoRet, &puchAlgo, cbAlgoRaw); 215 216 RTMemTmpFree(pvAlgoFree); 217 if (pOsslAlgoRet) 218 { 219 /* 220 * Do the decryption (en_de = 0). 221 */ 222 int cbDecrypted = 0; 223 unsigned char *puchDecrypted = NULL; 224 puchDecrypted = PKCS12_pbe_crypt(pOsslAlgoRet, pszPassword, (int)strlen(pszPassword), 225 pEncryptedKey->EncryptedData.Asn1Core.uData.puch, 226 (int)pEncryptedKey->EncryptedData.Asn1Core.cb, 227 &puchDecrypted, &cbDecrypted, 0 /*en_de*/); 228 if (puchDecrypted) 229 { 230 /* 231 * Transfer to a safer buffer and carefully wipe the OpenSSL buffer. 232 */ 233 uint8_t *pbFinal = (uint8_t *)RTMemSaferAllocZ(cbDecrypted); 234 if (pbFinal) 235 { 236 memcpy(pbFinal, puchDecrypted, cbDecrypted); 237 *ppbDecrypted = pbFinal; 238 *pcbDecrypted = cbDecrypted; 239 *pcbDecryptedAlloced = cbDecrypted; 240 rc = VINF_SUCCESS; 241 } 242 else 243 rc = VERR_NO_MEMORY; 244 RTMemWipeThoroughly(puchDecrypted, cbDecrypted, 3); 245 OPENSSL_free(puchDecrypted); 246 } 247 else 248 rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_DECRYPTION_FAILED, 249 "Incorrect password? d2i_X509_ALGOR failed (%u)", ERR_get_error()); 250 X509_ALGOR_free(pOsslAlgoRet); 251 } 252 else 253 rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_PKIX_OSSL_D2I_PRIVATE_KEY_FAILED /* close enough */, 254 "d2i_X509_ALGOR failed (%u)", ERR_get_error()); 255 return rc; 256 257 #else 258 RT_NOREF(pEncryptedKey, pszPassword, pErrInfo); 259 return VERR_CR_KEY_DECRYPTION_NOT_SUPPORTED; 260 #endif 261 } 123 262 124 263 … … 173 312 174 313 /* 175 * Do we support the ci hper?314 * Do we support the cipher? 176 315 */ 177 316 #ifdef IPRT_WITH_OPENSSL /** @todo abstract encryption & decryption. */ … … 471 610 472 611 case kKeyFormat_PrivateKeyInfo: 612 rc = rtCrKeyCreateFromPrivateKeyInfo(phKey, &PrimaryCursor, pSection->pbData, pSection->cbData, pErrInfo, pszErrorTag); 613 break; 614 615 case kKeyFormat_EncryptedPrivateKeyInfo: 473 616 { 474 617 RTAsn1CursorInitPrimary(&PrimaryCursor, pSection->pbData, (uint32_t)pSection->cbData, 475 618 pErrInfo, &g_RTAsn1DefaultAllocator, RTASN1CURSOR_FLAGS_DER, pszErrorTag); 476 RTCRPKCS8 PRIVATEKEYINFOPrivateKeyInfo;477 RT_ZERO( PrivateKeyInfo);478 rc = RTCrPkcs8 PrivateKeyInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &PrivateKeyInfo,479 pszErrorTag ? pszErrorTag : "PrivateKeyInfo");619 RTCRPKCS8ENCRYPTEDPRIVATEKEYINFO EncryptedPrivateKeyInfo; 620 RT_ZERO(EncryptedPrivateKeyInfo); 621 rc = RTCrPkcs8EncryptedPrivateKeyInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &EncryptedPrivateKeyInfo, 622 pszErrorTag ? pszErrorTag : "EncryptedPrivateKeyInfo"); 480 623 if (RT_SUCCESS(rc)) 481 624 { 482 /* 483 * Load the private key according to it's algorithm. 484 * We currently only support RSA (pkcs1-RsaEncryption). 485 */ 486 if (RTAsn1ObjId_CompareWithString(&PrivateKeyInfo.PrivateKeyAlgorithm.Algorithm, 487 RTCRX509ALGORITHMIDENTIFIERID_RSA) == 0) 488 rc = rtCrKeyCreateRsaPrivate(phKey, PrivateKeyInfo.PrivateKey.Asn1Core.uData.pv, 489 PrivateKeyInfo.PrivateKey.Asn1Core.cb, pErrInfo, pszErrorTag); 490 else 491 rc = RTErrInfoSet(pErrInfo, VERR_CR_KEY_FORMAT_NOT_SUPPORTED, 492 "Support for PKCS#8 PrivateKeyInfo for non-RSA keys is not yet implemented"); 625 uint8_t *pbDecrypted = NULL; 626 size_t cbDecrypted = 0; 627 size_t cbDecryptedAlloced = 0; 628 rc = rtCrKeyDecryptPkcs8Info(&EncryptedPrivateKeyInfo, pszPassword, 629 &pbDecrypted, &cbDecrypted, &cbDecryptedAlloced, pErrInfo); 630 if (RT_SUCCESS(rc)) 631 { 632 rc = rtCrKeyCreateFromPrivateKeyInfo(phKey, &PrimaryCursor, pbDecrypted, cbDecrypted, pErrInfo, pszErrorTag); 633 634 RTMemSaferFree(pbDecrypted, cbDecryptedAlloced); 635 } 636 RTCrPkcs8EncryptedPrivateKeyInfo_Delete(&EncryptedPrivateKeyInfo); 493 637 } 494 638 break; 495 639 } 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 640 502 641 default: -
trunk/src/VBox/Runtime/common/crypto/pkcs8-template.h
r100493 r100528 53 53 #undef RTASN1TMPL_INT_NAME 54 54 55 #if 056 55 57 56 /* 58 57 * Encrypted private key info 59 58 */ 60 #define RTASN1TMPL_TYPE RTCR ENCRYPTEDPRIVATEKEY61 #define RTASN1TMPL_EXT_NAME RTCr EncryptedPrivateKey62 #define RTASN1TMPL_INT_NAME rtCr EncryptedPrivateKey59 #define RTASN1TMPL_TYPE RTCRPKCS8ENCRYPTEDPRIVATEKEYINFO 60 #define RTASN1TMPL_EXT_NAME RTCrPkcs8EncryptedPrivateKeyInfo 61 #define RTASN1TMPL_INT_NAME rtCrPkcs8EncryptedPrivateKeyInfo 63 62 RTASN1TMPL_BEGIN_SEQCORE(); 64 63 RTASN1TMPL_MEMBER( EncryptionAlgorithm, RTCRX509ALGORITHMIDENTIFIER, RTCrX509AlgorithmIdentifier); … … 69 68 #undef RTASN1TMPL_INT_NAME 70 69 71 #endif -
trunk/src/VBox/Runtime/testcase/tstRTCrPkix-1.cpp
r100421 r100528 58 58 static const struct { unsigned cBits; const char *pszPrivateKey, *pszPublicKey, *pszPassword; } g_aKeyPairs[] = 59 59 { 60 #if 0 60 61 { 61 62 4096, … … 256 257 "password" 257 258 }, 258 259 #endif 259 260 /* 260 261 * PKCS8 Test Keys … … 285 286 "-----END PUBLIC KEY-----\n", 286 287 NULL 287 } 288 }, 289 { 290 2048, 291 "-----BEGIN ENCRYPTED PRIVATE KEY-----\n" 292 "MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIRFetWFFFIb4CAggA\n" 293 "MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBAZMr0Lq1s+olU2jUY8MuQJBIIE\n" 294 "0ICOZE6GhPCQbUSudbBYTG4zBRGhJOTeGF43c3pqi6UNS4qWK9IQ3B5hm618Iof0\n" 295 "YUnCDKy9G7TPMwP+8pcybFXuvWo1yeJcVGNalBq/LmUG2RBJ3hh/IikDnzj2jq1u\n" 296 "QKFTgl5yZ41bC75d81fdg0CpYqIGOjLdQcUJmVk+lKggWcN7KuqPj+9FhCoRyjIp\n" 297 "UyLYQQ8E0sb7tk0gJoi6VHddTYpLEDiFzGqXP/XWykCFHx977sbRuOymrTF3C3OZ\n" 298 "X5PSkszydSBzomPl1MnmiMjAmgc3j6EABUpzjaUZ2l2xxeM9r/c076zSpHdcBFus\n" 299 "Y3pA9Hm9HvV2q+1FHHNk90vZlXWtyTh8tSJvT3WF63kYMyIXXztovldjxX76fxB0\n" 300 "c5K0E9FH5sjv0R4AfMf4CMsP5InGfy2zICRwi+xvp97lq6nEXjIqiePyNTUA3QAy\n" 301 "brZtzM67KxFL/TuV6Y20DILAPlWZe3C8KFpFeHEi5yddi0VikzQVl1X/hieCt4SP\n" 302 "aTdd+MCn3XIu+58RK6UYCVCxbH9j9iZCznOfWLRMpthvoa9SO8M8DTFlx/bptClt\n" 303 "IKUnsQgBpvT3+xzpJk4sQyD4aZDcDMQeNfDr/1KyYMEjaqvGMqKfLed2HLDHdD9f\n" 304 "rsg41wTCqp/draUh2qxa7pXkK0KcNbH4hLH//pduaLubHmOPofLvprVIISyOtspN\n" 305 "tsPtXs43Ta4dOQWLg2Q/lwlo0psi1im/fHKyr7rpMdUa+dRGX8H4tYsFJufHzVjr\n" 306 "rQrKDHPsNfhy+JuCfQu/8SdZCXwcBxxeSlam5EgtlfsTDC+zIP8dDHaOWsDRm+k3\n" 307 "ryKTSn84LBQLWzc3RhZteAlzDHcmrS/MmF4yfpgSkFI+aUF5+XPLqoYVsoVKQ5bL\n" 308 "NnA6xJBkXVtzNZUYH3cHoiAOATlhHRFtoWrKoEQXlCNvvTCiBGoMPfjpnTy3u/kS\n" 309 "8JaUsJLvDFQBFPSxdYA+w/zb3zy0Nh5s3R9D6IkrH0X2mk8JhABYNzDIDYlS2Ioz\n" 310 "ARpmwuZwPUG1iSzamYZCt2OVd1acPexiwTATihfPVT2RFbHET9+e7NX/5TFnGP++\n" 311 "4o6mckiD5c9QmwE29FLTeiqwKvLweLrrF6/1/S45/okibqXHgh7O567y+PSMmjk5\n" 312 "L0azEmv6UIs5z4FNvDxS5++b3oqUMu+oazQP1aDk0H/8xJaDFrnOKWL9h8waeBn7\n" 313 "JBuuIFKqRb6S9H0ZPb1R7Z9BVuUil76nc4zr0kLNdJ8dq2l/kcqIIFrtVJX/INaf\n" 314 "gYvlsIYXpb/IhBZit1GJxwi8kk29b2QSyDW6CNNi3dC8Y1p9jiLejqFM4LQL/HNr\n" 315 "atc1pUBPePK1ZHJ0OLyVthJYXmn8v+M9eHfptQzBZpILTZZK719uOtHloPrI64LY\n" 316 "iO00glzBju2W1yDF6cTgmWQEigWno65Is5pjN5ByMf3ouHM8qJFIhTEqCpAY7cQQ\n" 317 "2k6o7dqAcQm7Q+BvhfsWcPWq/GH/OOkuUDqQaK1YDA+lUj9uyrxm9AlrDtUjezLE\n" 318 "k3IT6ZiBVrPlKWCMbT6ajm9ti0RuCRnZfrrLn2gu16weRtaNeVyza6D5wn+eKXmE\n" 319 "5dnugDd6T+QBX/3+WLaXTL3l/tj7i9WwNJU4uqW7y6+P\n" 320 "-----END ENCRYPTED PRIVATE KEY-----\n", 321 "-----BEGIN PUBLIC KEY-----\n" 322 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp6CMrt0Z/k5+c/7C3oWz\n" 323 "bLBmE4fttE84EZsrwB/ZDhMBQDsVF/GMePj1e5zrxnVq6GZhcNbcJTqHp0mWb+K5\n" 324 "HMlAihPKYlswJQtkVgp/czbdXwt3MI+D4ifUiq4v8AMrJHW+AYd0GYKzYma6LGVj\n" 325 "75Bue450bsLocMKwB03iyFE8SBwzGSj9jwJ9UYBvVUnNsutq6nCPTj1bM6naFIHO\n" 326 "Y+cozHIrKyvHGHoWBVUqKARlNT3TtbTyGxaT4QyZj8Pm9jB5Np6CrF7nmV936Q3A\n" 327 "3CHji8BbhfcdZ/9s53wkSwztfpe8NYh1/RiLZtZdky9E6Q67dt3h4bKHsKRFi0xW\n" 328 "jQIDAQAB\n" 329 "-----END PUBLIC KEY-----\n", 330 "password" 331 }, 288 332 }; 289 333
Note:
See TracChangeset
for help on using the changeset viewer.