Changeset 100442 in vbox for trunk/src/VBox/Runtime/common/crypto/x509-core.cpp
- Timestamp:
- Jul 8, 2023 11:10:51 AM (19 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/crypto/x509-core.cpp
r100364 r100442 45 45 #include <iprt/string.h> 46 46 #include <iprt/uni.h> 47 #include <iprt/crypto/pkix.h> 48 #ifdef RT_STRICT 49 # include <iprt/crypto/digest.h> 50 #endif 47 51 48 52 #include "x509-internal.h" 53 54 55 /********************************************************************************************************************************* 56 * Internal Functions * 57 *********************************************************************************************************************************/ 58 #ifdef RT_STRICT 59 static void rtCrX509AlgorithmIdentifier_AssertTableSanityAndMore(void); 60 #endif 49 61 50 62 … … 73 85 */ 74 86 75 RTDECL(RTDIGESTTYPE) RTCrX509AlgorithmIdentifier_QueryDigestType(PCRTCRX509ALGORITHMIDENTIFIER pThis) 87 /** 88 * String table with the encryption OIDs (used by g_aSignatureOidInfo). 89 */ 90 static const char * const g_apszEncryptionOids[] = 91 { 92 NULL, 93 #define IDX_ENCRYPTION_NIL 0 94 RTCR_X962_ECDSA_OID, 95 #define IDX_ENCRYPTION_ECDSA 1 96 RTCR_PKCS1_RSA_OID, 97 #define IDX_ENCRYPTION_RSA 2 98 }; 99 100 /** 101 * Information about an algorithm identifier. 102 */ 103 typedef struct RTCRX509ALGORITHIDENTIFIERINTERNALINFO 104 { 105 /** The signature OID. */ 106 const char *pszSignatureOid; 107 /** Index into g_apszEncryptionOids of the encryption ODI. 108 * This is IDX_ENCRYPTION_NIL for hashes. */ 109 uint8_t idxEncryption; 110 /** The message digest type specified by the OID. 111 * This is set to RTDIGESTTYPE_INVALID in two cases: 112 * 1. Pure encryption algorithm OID (cBitsDigest also zero). 113 * 2. The hash is so esoteric that IPRT doesn't support it. */ 114 uint8_t enmDigestType; 115 /** The digest size in bits. 116 * This is ZERO if the OID does not include an hash. */ 117 uint16_t cBitsDigest; 118 } RTCRX509ALGORITHIDENTIFIERINTERNALINFO; 119 typedef RTCRX509ALGORITHIDENTIFIERINTERNALINFO const *PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO; 120 121 /** 122 * Signature to encryption OID. 123 * 124 * @note This is sorted to allow binary searching. 125 * @note This origins in pkix-utils.cpp, which is why it uses the other set of 126 * OID defines. 127 */ 128 static RTCRX509ALGORITHIDENTIFIERINTERNALINFO const g_aSignatureOidInfo[] = 129 { 130 { /*1.0.10118.3.0.55*/ RTCRX509ALGORITHMIDENTIFIERID_WHIRLPOOL, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_INVALID, 512, }, 131 132 { /*1.2.840.10045.2.1 */ RTCR_X962_ECDSA_OID, IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_INVALID, 0, }, 133 { /*1.2.840.10045.4.1 */ RTCR_X962_ECDSA_WITH_SHA1_OID, IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA1, 160, }, 134 { /*1.2.840.10045.4.3.1 */ RTCR_X962_ECDSA_WITH_SHA224_OID, IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA224, 224, }, 135 { /*1.2.840.10045.4.3.2 */ RTCR_X962_ECDSA_WITH_SHA256_OID, IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA256, 256, }, 136 { /*1.2.840.10045.4.3.3 */ RTCR_X962_ECDSA_WITH_SHA384_OID, IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA384, 384, }, 137 { /*1.2.840.10045.4.3.4 */ RTCR_X962_ECDSA_WITH_SHA512_OID, IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA512, 512, }, 138 139 { /*1.2.840.113549.1.1.1 */ RTCR_PKCS1_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_INVALID, 0, }, 140 { /*1.2.840.113549.1.1.11*/ RTCR_PKCS1_SHA256_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_SHA256, 256, }, 141 { /*1.2.840.113549.1.1.12*/ RTCR_PKCS1_SHA384_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_SHA384, 384, }, 142 { /*1.2.840.113549.1.1.13*/ RTCR_PKCS1_SHA512_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_SHA512, 512, }, 143 { /*1.2.840.113549.1.1.14*/ RTCR_PKCS1_SHA224_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_SHA224, 224, }, 144 { /*1.2.840.113549.1.1.15*/ RTCR_PKCS1_SHA512T224_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_SHA512T224, 224, }, 145 { /*1.2.840.113549.1.1.16*/ RTCR_PKCS1_SHA512T256_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_SHA512T256, 256, }, 146 { /*1.2.840.113549.1.1.2*/ RTCR_PKCS1_MD2_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_MD2, 128, }, 147 { /*1.2.840.113549.1.1.3*/ RTCR_PKCS1_MD4_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_MD4, 128, }, 148 { /*1.2.840.113549.1.1.4*/ RTCR_PKCS1_MD5_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_MD5, 128, }, 149 { /*1.2.840.113549.1.1.5*/ RTCR_PKCS1_SHA1_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_SHA1, 160, }, 150 151 { /*1.2.840.113549.2.2*/ RTCRX509ALGORITHMIDENTIFIERID_MD2, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_MD2, 128, }, 152 { /*1.2.840.113549.2.4*/ RTCRX509ALGORITHMIDENTIFIERID_MD4, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_MD4, 128, }, 153 { /*1.2.840.113549.2.5*/ RTCRX509ALGORITHMIDENTIFIERID_MD5, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_MD5, 128, }, 154 155 /* oddballs for which we don't support the padding (skip?): */ 156 //{ "1.3.14.3.2.11" /*rsaSignature*/, IDX_ENCRYPTION_RSA/*?*/, RTDIGESTTYPE_INVALID, 0, }, 157 { "1.3.14.3.2.14" /*mdc2WithRSASignature w/ 9796-2 padding*/, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_INVALID, 0, }, 158 //{ "1.3.14.3.2.15" /*sha0WithRSASignature w/ 9796-2 padding*/, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_INVALID, 160, }, 159 { "1.3.14.3.2.24" /*md2WithRSASignature w/ 9796-2 padding*/, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_MD2, 128, }, 160 { "1.3.14.3.2.25" /*md5WithRSASignature w/ 9796-2 padding*/, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_MD5, 128, }, 161 { /*1.3.14.3.2.26*/ RTCRX509ALGORITHMIDENTIFIERID_SHA1, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA1, 160, }, 162 { "1.3.14.3.2.29" /*sha1WithRSAEncryption (obsolete?)*/, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_SHA1, 160, }, 163 164 { /*2.16.840.1.101.3.4.2.1*/ RTCRX509ALGORITHMIDENTIFIERID_SHA256, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA256, 256, }, 165 { /*2.16.840.1.101.3.4.2.10*/ RTCRX509ALGORITHMIDENTIFIERID_SHA3_512, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA3_512, 512, }, 166 { /*2.16.840.1.101.3.4.2.2*/ RTCRX509ALGORITHMIDENTIFIERID_SHA384, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA384, 384, }, 167 { /*2.16.840.1.101.3.4.2.3*/ RTCRX509ALGORITHMIDENTIFIERID_SHA512, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA512, 512, }, 168 { /*2.16.840.1.101.3.4.2.4*/ RTCRX509ALGORITHMIDENTIFIERID_SHA224, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA224, 224, }, 169 { /*2.16.840.1.101.3.4.2.5*/ RTCRX509ALGORITHMIDENTIFIERID_SHA512T224,IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA512T224, 224, }, 170 { /*2.16.840.1.101.3.4.2.6*/ RTCRX509ALGORITHMIDENTIFIERID_SHA512T256,IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA512T256, 256, }, 171 { /*2.16.840.1.101.3.4.2.7*/ RTCRX509ALGORITHMIDENTIFIERID_SHA3_224, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA3_224, 224, }, 172 { /*2.16.840.1.101.3.4.2.8*/ RTCRX509ALGORITHMIDENTIFIERID_SHA3_256, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA3_256, 256, }, 173 { /*2.16.840.1.101.3.4.2.9*/ RTCRX509ALGORITHMIDENTIFIERID_SHA3_384, IDX_ENCRYPTION_NIL, RTDIGESTTYPE_SHA3_384, 384, }, 174 175 { /*2.16.840.1.101.3.4.3.10*/ RTCR_NIST_SHA3_256_WITH_ECDSA_OID, IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA3_256, 256, }, 176 { /*2.16.840.1.101.3.4.3.11*/ RTCR_NIST_SHA3_384_WITH_ECDSA_OID, IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA3_384, 384, }, 177 { /*2.16.840.1.101.3.4.3.12*/ RTCR_NIST_SHA3_512_WITH_ECDSA_OID, IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA3_512, 512, }, 178 { /*2.16.840.1.101.3.4.3.13*/ RTCR_NIST_SHA3_224_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_SHA3_224, 224, }, 179 { /*2.16.840.1.101.3.4.3.14*/ RTCR_NIST_SHA3_256_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_SHA3_256, 256, }, 180 { /*2.16.840.1.101.3.4.3.15*/ RTCR_NIST_SHA3_384_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_SHA3_384, 384, }, 181 { /*2.16.840.1.101.3.4.3.16*/ RTCR_NIST_SHA3_512_WITH_RSA_OID, IDX_ENCRYPTION_RSA, RTDIGESTTYPE_SHA3_512, 512, }, 182 { /*2.16.840.1.101.3.4.3.9*/ RTCR_NIST_SHA3_224_WITH_ECDSA_OID, IDX_ENCRYPTION_ECDSA, RTDIGESTTYPE_SHA3_224, 224, }, 183 }; 184 185 /** 186 * Encryption and digest combining. 187 * 188 * This is a subset of g_aSignatureOidInfo. 189 * @todo Organize this more efficiently... 190 */ 191 typedef struct RTCRX509ALGORITHIDENTIFIERCOMBINING 192 { 193 const char *pszDigestOid; 194 const char *pszEncryptedDigestOid; 195 } RTCRX509ALGORITHIDENTIFIERCOMBINING; 196 typedef RTCRX509ALGORITHIDENTIFIERCOMBINING const *PCRTCRX509ALGORITHIDENTIFIERCOMBINING; 197 198 #undef MY_COMBINE 199 #define MY_COMBINE(a_Encrypt, a_Digest) \ 200 { RTCRX509ALGORITHMIDENTIFIERID_ ## a_Digest, \ 201 RTCRX509ALGORITHMIDENTIFIERID_ ## a_Digest ## _WITH_ ## a_Encrypt } 202 203 /** Digest and encryption combinations for ECDSA. */ 204 static RTCRX509ALGORITHIDENTIFIERCOMBINING const g_aDigestAndEncryptionEcdsa[] = 205 { 206 MY_COMBINE(ECDSA, SHA1), 207 MY_COMBINE(ECDSA, SHA224), 208 MY_COMBINE(ECDSA, SHA256), 209 MY_COMBINE(ECDSA, SHA384), 210 MY_COMBINE(ECDSA, SHA512), 211 MY_COMBINE(ECDSA, SHA3_224), 212 MY_COMBINE(ECDSA, SHA3_256), 213 MY_COMBINE(ECDSA, SHA3_384), 214 MY_COMBINE(ECDSA, SHA3_512), 215 }; 216 217 /** Digest and encryption combinations for RSA. */ 218 static RTCRX509ALGORITHIDENTIFIERCOMBINING const g_aDigestAndEncryptionRsa[] = 219 { 220 MY_COMBINE(RSA, SHA1), 221 MY_COMBINE(RSA, SHA256), 222 MY_COMBINE(RSA, SHA512), 223 MY_COMBINE(RSA, SHA384), 224 MY_COMBINE(RSA, MD5), 225 MY_COMBINE(RSA, MD2), 226 MY_COMBINE(RSA, MD4), 227 MY_COMBINE(RSA, SHA224), 228 MY_COMBINE(RSA, SHA512T224), 229 MY_COMBINE(RSA, SHA512T256), 230 MY_COMBINE(RSA, SHA3_224), 231 MY_COMBINE(RSA, SHA3_256), 232 MY_COMBINE(RSA, SHA3_384), 233 MY_COMBINE(RSA, SHA3_512), 234 }; 235 236 #undef MY_COMBINE 237 238 /** 239 * Table running parallel to g_apszEncryptionOids. 240 */ 241 static struct 242 { 243 PCRTCRX509ALGORITHIDENTIFIERCOMBINING paCombinations; 244 size_t cCombinations; 245 } const g_aDigestAndEncryption[] = 246 { 247 /* [IDX_ENCRYPTION_NIL] = */ { NULL, 0 }, 248 /* [IDX_ENCRYPTION_ECDSA] = */ { &g_aDigestAndEncryptionEcdsa[0], RT_ELEMENTS(g_aDigestAndEncryptionEcdsa) }, 249 /* [IDX_ENCRYPTION_RSA] = */ { &g_aDigestAndEncryptionRsa[0], RT_ELEMENTS(g_aDigestAndEncryptionRsa) }, 250 }; 251 AssertCompile(IDX_ENCRYPTION_NIL == 0 && IDX_ENCRYPTION_ECDSA == 1 && IDX_ENCRYPTION_RSA == 2); 252 253 254 /** 255 * Looks up info we've got on a algorithm identifier. 256 */ 257 static PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO rtCrX509AlgorithmIdentifier_LookupInfoByOid(const char *pszSignatureOid) 258 { 259 #ifdef RT_STRICT 260 /* 261 * Do internal santiy checking on first call. 262 */ 263 static bool volatile s_fChecked = false; 264 if (RT_LIKELY(s_fChecked)) 265 { /* likely */ } 266 else 267 { 268 s_fChecked = true; /* Must be set before the call, as the callee will calls us again. */ 269 rtCrX509AlgorithmIdentifier_AssertTableSanityAndMore(); 270 } 271 #endif 272 273 /* 274 * Do a binary search of g_aSignatureOidInfo. 275 */ 276 size_t iFirst = 0; 277 size_t iEnd = RT_ELEMENTS(g_aSignatureOidInfo); 278 for (;;) 279 { 280 size_t const i = iFirst + (iEnd - iFirst) / 2; 281 int const iDiff = strcmp(pszSignatureOid, g_aSignatureOidInfo[i].pszSignatureOid); 282 if (iDiff < 0) 283 { 284 if (i > iFirst) 285 iEnd = i; 286 else 287 return NULL; 288 } 289 else if (iDiff > 0) 290 { 291 if (i + 1 < iEnd) 292 iFirst = i + 1; 293 else 294 return NULL; 295 } 296 else 297 return &g_aSignatureOidInfo[i]; 298 } 299 } 300 301 #ifdef RT_STRICT 302 /** 303 * Check that the g_aSignatureOidInfo and g_aDigestAndEncryption makes sense and 304 * matches up with one another and other IPRT information sources. 305 */ 306 static void rtCrX509AlgorithmIdentifier_AssertTableSanityAndMore(void) 307 { 308 /* Check that binary searching work and that digest info matches up: */ 309 for (size_t i = 1; i < RT_ELEMENTS(g_aSignatureOidInfo); i++) 310 Assert(strcmp(g_aSignatureOidInfo[i].pszSignatureOid, g_aSignatureOidInfo[i - 1].pszSignatureOid) > 0); 311 for (size_t i = 0; i < RT_ELEMENTS(g_aSignatureOidInfo); i++) 312 { 313 PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pInfo 314 = rtCrX509AlgorithmIdentifier_LookupInfoByOid(g_aSignatureOidInfo[i].pszSignatureOid); 315 Assert(pInfo && pInfo->pszSignatureOid == g_aSignatureOidInfo[i].pszSignatureOid); 316 317 /* If the digest type is RTDIGESTTYPE_INVALID, we must have an pure encryption entry or an obscure hash function. */ 318 if (g_aSignatureOidInfo[i].enmDigestType != RTDIGESTTYPE_INVALID) 319 Assert( RTCrDigestTypeToHashSize((RTDIGESTTYPE)g_aSignatureOidInfo[i].enmDigestType) * 8 320 == g_aSignatureOidInfo[i].cBitsDigest); 321 else 322 Assert(g_aSignatureOidInfo[i].cBitsDigest == 0 || g_aSignatureOidInfo[i].idxEncryption == IDX_ENCRYPTION_NIL); 323 324 # ifdef IN_RING3 325 /* Check with the RTCrDigestFindByObjIdString API: */ 326 RTDIGESTTYPE enmDigestType2 = (RTDIGESTTYPE)g_aSignatureOidInfo[i].enmDigestType; 327 # if defined(IPRT_WITHOUT_DIGEST_MD2) || defined(IPRT_WITHOUT_DIGEST_MD4) || defined(IPRT_WITHOUT_DIGEST_MD5) \ 328 || defined(IPRT_WITHOUT_SHA512T224) || defined(IPRT_WITHOUT_SHA512T256) || defined(IPRT_WITHOUT_SHA3) 329 switch (enmDigestType2) 330 { 331 default: break; 332 # ifdef IPRT_WITHOUT_DIGEST_MD2 333 case RTDIGESTTYPE_MD2: 334 # endif 335 # ifdef IPRT_WITHOUT_DIGEST_MD4 336 case RTDIGESTTYPE_MD4: 337 # endif 338 # ifdef IPRT_WITHOUT_DIGEST_MD5 339 case RTDIGESTTYPE_MD5: 340 # endif 341 # ifdef IPRT_WITHOUT_SHA512T224 342 case RTDIGESTTYPE_SHA512T224: 343 # endif 344 # ifdef IPRT_WITHOUT_SHA512T256 345 case RTDIGESTTYPE_SHA512T256: 346 # endif 347 # ifdef IPRT_WITHOUT_SHA3 348 case RTDIGESTTYPE_SHA3_224: 349 case RTDIGESTTYPE_SHA3_256: 350 case RTDIGESTTYPE_SHA3_384: 351 case RTDIGESTTYPE_SHA3_512: 352 # endif 353 enmDigestType2 = RTDIGESTTYPE_INVALID; 354 break; 355 } 356 # endif 357 PCRTCRDIGESTDESC const pDigestDesc = RTCrDigestFindByObjIdString(g_aSignatureOidInfo[i].pszSignatureOid, 358 NULL /*ppvOpaque*/); 359 if (pDigestDesc) 360 { 361 AssertMsg(pDigestDesc->enmType == enmDigestType2, 362 ("%s pDigestDesc=%s enmDigestType2=%s\n", g_aSignatureOidInfo[i].pszSignatureOid, 363 RTCrDigestTypeToName(pDigestDesc->enmType), RTCrDigestTypeToName(enmDigestType2))); 364 Assert(pDigestDesc->cbHash * 8 == g_aSignatureOidInfo[i].cBitsDigest); 365 } 366 else 367 AssertMsg(enmDigestType2 == RTDIGESTTYPE_INVALID, 368 ("%s enmDigestType2=%s\n", g_aSignatureOidInfo[i].pszSignatureOid, RTCrDigestTypeToName(enmDigestType2))); 369 # endif /* IN_RING3 */ 370 371 372 # ifdef IN_RING3 373 /* Look it up the encryption descriptor. */ 374 const char * const pszCheckEncryptId = g_apszEncryptionOids[g_aSignatureOidInfo[i].idxEncryption]; 375 PCRTCRPKIXSIGNATUREDESC const pSigDesc = RTCrPkixSignatureFindByObjIdString(g_aSignatureOidInfo[i].pszSignatureOid, 376 NULL /*ppvOpaque*/); 377 if (pSigDesc) 378 Assert(pszCheckEncryptId && strcmp(pSigDesc->pszObjId, pszCheckEncryptId) == 0); 379 # ifdef IPRT_WITH_OPENSSL /* No ECDSA implementation w/o OpenSSL at the moment. */ 380 else 381 AssertMsg(!pSigDesc && pInfo->idxEncryption == IDX_ENCRYPTION_NIL, ("%s\n", g_aSignatureOidInfo[i].pszSignatureOid)); 382 # endif 383 # endif /* IN_RING3 */ 384 } 385 386 /* 387 * Check that everything in g_aDigestAndEncryption is resolvable here and that the info matches up. 388 */ 389 for (size_t idxEncryption = IDX_ENCRYPTION_NIL; idxEncryption < RT_ELEMENTS(g_aDigestAndEncryption); idxEncryption++) 390 { 391 PCRTCRX509ALGORITHIDENTIFIERCOMBINING const paCombinations = g_aDigestAndEncryption[idxEncryption].paCombinations; 392 size_t const cCombinations = g_aDigestAndEncryption[idxEncryption].cCombinations; 393 for (size_t i = 0; i < cCombinations; i++) 394 { 395 PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pInfo 396 = rtCrX509AlgorithmIdentifier_LookupInfoByOid(paCombinations[i].pszEncryptedDigestOid); 397 AssertContinue(pInfo); 398 Assert(strcmp(paCombinations[i].pszEncryptedDigestOid, pInfo->pszSignatureOid) == 0); 399 Assert(pInfo->idxEncryption == idxEncryption); 400 Assert(strcmp(paCombinations[i].pszDigestOid, 401 RTCrDigestTypeToAlgorithmOid((RTDIGESTTYPE)pInfo->enmDigestType)) == 0); 402 } 403 } 404 } 405 #endif /* RT_STRICT */ 406 407 408 RTDECL(RTDIGESTTYPE) RTCrX509AlgorithmIdentifier_GetDigestType(PCRTCRX509ALGORITHMIDENTIFIER pThis, bool fPureDigestsOnly) 76 409 { 77 410 AssertPtrReturn(pThis, RTDIGESTTYPE_INVALID); 78 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD5)) 79 return RTDIGESTTYPE_MD5; 80 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA1)) 81 return RTDIGESTTYPE_SHA1; 82 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA256)) 83 return RTDIGESTTYPE_SHA256; 84 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512)) 85 return RTDIGESTTYPE_SHA512; 86 87 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA384)) 88 return RTDIGESTTYPE_SHA384; 89 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA224)) 90 return RTDIGESTTYPE_SHA224; 91 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512T224)) 92 return RTDIGESTTYPE_SHA512T224; 93 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512T256)) 94 return RTDIGESTTYPE_SHA512T256; 95 96 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_224)) 97 return RTDIGESTTYPE_SHA3_224; 98 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_256)) 99 return RTDIGESTTYPE_SHA3_256; 100 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_384)) 101 return RTDIGESTTYPE_SHA3_384; 102 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_512)) 103 return RTDIGESTTYPE_SHA3_512; 104 return RTDIGESTTYPE_INVALID; 105 } 106 107 108 RTDECL(uint32_t) RTCrX509AlgorithmIdentifier_QueryDigestSize(PCRTCRX509ALGORITHMIDENTIFIER pThis) 411 PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pInfo = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pThis->Algorithm.szObjId); 412 return pInfo && (!fPureDigestsOnly || pInfo->idxEncryption == IDX_ENCRYPTION_NIL) 413 ? (RTDIGESTTYPE)pInfo->enmDigestType : RTDIGESTTYPE_INVALID; 414 } 415 416 417 RTDECL(uint32_t) RTCrX509AlgorithmIdentifier_GetDigestSize(PCRTCRX509ALGORITHMIDENTIFIER pThis, bool fPureDigestsOnly) 109 418 { 110 419 AssertPtrReturn(pThis, UINT32_MAX); 111 112 /* common */ 113 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD5)) 114 return 128 / 8; 115 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA1)) 116 return 160 / 8; 117 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA256)) 118 return 256 / 8; 119 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512)) 120 return 512 / 8; 121 122 /* Less common. */ 123 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD2)) 124 return 128 / 8; 125 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_MD4)) 126 return 128 / 8; 127 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA384)) 128 return 384 / 8; 129 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA224)) 130 return 224 / 8; 131 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512T224)) 132 return 224 / 8; 133 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA512T256)) 134 return 256 / 8; 135 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_224)) 136 return 224 / 8; 137 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_256)) 138 return 256 / 8; 139 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_384)) 140 return 384 / 8; 141 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_SHA3_512)) 142 return 512 / 8; 143 if (!strcmp(pThis->Algorithm.szObjId, RTCRX509ALGORITHMIDENTIFIERID_WHIRLPOOL)) 144 return 512 / 8; 145 146 return UINT32_MAX; 420 PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pInfo = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pThis->Algorithm.szObjId); 421 return pInfo && (!fPureDigestsOnly || pInfo->idxEncryption == IDX_ENCRYPTION_NIL) 422 ? pInfo->cBitsDigest / 8 : UINT32_MAX; 147 423 } 148 424 … … 157 433 const char *pszEncryptedDigestOid) 158 434 { 159 /* common */ 160 if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD5)) 161 { 162 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD5_WITH_RSA)) 163 return 0; 164 } 165 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA1)) 166 { 167 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA1_WITH_RSA)) 168 return 0; 169 } 170 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA256)) 171 { 172 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA256_WITH_RSA)) 173 return 0; 174 } 175 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512)) 176 { 177 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512_WITH_RSA)) 178 return 0; 179 } 180 /* Less common. */ 181 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD2)) 182 { 183 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD2_WITH_RSA)) 184 return 0; 185 } 186 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD4)) 187 { 188 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD4_WITH_RSA)) 189 return 0; 190 } 191 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA384)) 192 { 193 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA384_WITH_RSA)) 194 return 0; 195 } 196 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA224)) 197 { 198 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA224_WITH_RSA)) 199 return 0; 200 } 201 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T224)) 202 { 203 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T224_WITH_RSA)) 204 return 0; 205 } 206 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T256)) 207 { 208 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T256_WITH_RSA)) 209 return 0; 210 } 211 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_224)) 212 { 213 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_224_WITH_RSA)) 214 return 0; 215 } 216 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_256)) 217 { 218 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_256_WITH_RSA)) 219 return 0; 220 } 221 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_384)) 222 { 223 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_384_WITH_RSA)) 224 return 0; 225 } 226 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_512)) 227 { 228 if (!strcmp(pszEncryptedDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_512_WITH_RSA)) 229 return 0; 230 } 231 else if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_WHIRLPOOL)) 232 { 233 /* ?? */ 234 } 235 else 236 return -1; 237 return 1; 435 /* 436 * Lookup the digest and encrypted digest OIDs. 437 */ 438 PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pDigest = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pszDigestOid); 439 AssertMsgReturn(pDigest, ("pszDigestOid=%s\n", pszDigestOid), -1); 440 AssertMsgReturn(pDigest->idxEncryption == IDX_ENCRYPTION_NIL, ("pszDigestOid=%s\n", pszDigestOid), -1); 441 AssertMsgReturn(pDigest->cBitsDigest != 0, ("pszDigestOid=%s\n", pszDigestOid), -1); 442 443 PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pEncrypt = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pszEncryptedDigestOid); 444 AssertMsgReturn(pEncrypt, ("pszEncryptedDigestOid=%s\n", pszEncryptedDigestOid), 1); 445 AssertMsgReturn(pEncrypt->idxEncryption != IDX_ENCRYPTION_NIL, ("pszEncryptedDigestOid=%s\n", pszEncryptedDigestOid), 1); 446 AssertMsgReturn(pEncrypt->enmDigestType != RTDIGESTTYPE_INVALID, ("pszEncryptedDigestOid=%s\n", pszEncryptedDigestOid), 1); 447 448 return pDigest->enmDigestType == pEncrypt->enmDigestType ? 0 : 1; 238 449 } 239 450 … … 249 460 const char *pszDigestOid) 250 461 { 251 /* RSA: */ 252 if (!strcmp(pszEncryptionOid, RTCRX509ALGORITHMIDENTIFIERID_RSA)) 253 { 254 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD5) 255 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD5_WITH_RSA)) 256 return RTCRX509ALGORITHMIDENTIFIERID_MD5_WITH_RSA; 257 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA1) 258 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA1_WITH_RSA)) 259 return RTCRX509ALGORITHMIDENTIFIERID_SHA1_WITH_RSA; 260 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA256) 261 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA256_WITH_RSA)) 262 return RTCRX509ALGORITHMIDENTIFIERID_SHA256_WITH_RSA; 263 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512) 264 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512_WITH_RSA)) 265 return RTCRX509ALGORITHMIDENTIFIERID_SHA512_WITH_RSA; 266 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD2) 267 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD2_WITH_RSA)) 268 return RTCRX509ALGORITHMIDENTIFIERID_MD2_WITH_RSA; 269 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD4) 270 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_MD4_WITH_RSA)) 271 return RTCRX509ALGORITHMIDENTIFIERID_MD4_WITH_RSA; 272 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA384) 273 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA384_WITH_RSA)) 274 return RTCRX509ALGORITHMIDENTIFIERID_SHA384_WITH_RSA; 275 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA224) 276 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA224_WITH_RSA)) 277 return RTCRX509ALGORITHMIDENTIFIERID_SHA224_WITH_RSA; 278 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T224) 279 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T224_WITH_RSA)) 280 return RTCRX509ALGORITHMIDENTIFIERID_SHA512T224_WITH_RSA; 281 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T256) 282 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA512T256_WITH_RSA)) 283 return RTCRX509ALGORITHMIDENTIFIERID_SHA512T256_WITH_RSA; 284 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_224) 285 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_224_WITH_RSA)) 286 return RTCRX509ALGORITHMIDENTIFIERID_SHA3_224_WITH_RSA; 287 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_256) 288 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_256_WITH_RSA)) 289 return RTCRX509ALGORITHMIDENTIFIERID_SHA3_256_WITH_RSA; 290 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_384) 291 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_384_WITH_RSA)) 292 return RTCRX509ALGORITHMIDENTIFIERID_SHA3_384_WITH_RSA; 293 if ( !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_512) 294 || !strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_SHA3_512_WITH_RSA)) 295 return RTCRX509ALGORITHMIDENTIFIERID_SHA3_512_WITH_RSA; 296 297 /* if (!strcmp(pszDigestOid, RTCRX509ALGORITHMIDENTIFIERID_WHIRLPOOL)) 298 return ???; */ 299 } 300 else if (RTCrX509AlgorithmIdentifier_CompareDigestOidAndEncryptedDigestOid(pszDigestOid, pszEncryptionOid) == 0) 301 return pszEncryptionOid; 302 303 AssertMsgFailed(("enc=%s hash=%s\n", pszEncryptionOid, pszDigestOid)); 462 /* 463 * We can look up the two OIDs and see what they actually are. 464 */ 465 /* The digest OID should be a pure hash algorithm, however we also accept 466 the already combined algorithm. */ 467 PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pDigest = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pszDigestOid); 468 AssertReturn(pDigest, NULL); 469 AssertReturn(pDigest->enmDigestType != RTDIGESTTYPE_INVALID, NULL); 470 471 /* The encryption OID should be a pure encryption algorithm, however we 472 also accept the already combined algorithm. */ 473 PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pEncrypt = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pszEncryptionOid); 474 AssertReturn(pEncrypt, NULL); 475 uint8_t const idxEncryption = pEncrypt->idxEncryption; 476 AssertReturn(idxEncryption != IDX_ENCRYPTION_NIL, NULL); 477 Assert(idxEncryption < RT_ELEMENTS(g_aDigestAndEncryption)); 478 479 /* Is the encryption OID purely encryption? */ 480 if (pEncrypt->cBitsDigest == 0) 481 { 482 Assert(pEncrypt->enmDigestType == RTDIGESTTYPE_INVALID); 483 484 /* Identify the slice of the table related to this encryption OID: */ 485 PCRTCRX509ALGORITHIDENTIFIERCOMBINING const paCombinations = g_aDigestAndEncryption[idxEncryption].paCombinations; 486 size_t const cCombinations = g_aDigestAndEncryption[idxEncryption].cCombinations; 487 488 /* Is the digest OID purely a digest? */ 489 if (pDigest->idxEncryption == IDX_ENCRYPTION_NIL) 490 { 491 for (size_t i = 0; i < cCombinations; i++) 492 if (!strcmp(pszDigestOid, paCombinations[i].pszDigestOid)) 493 return paCombinations[i].pszEncryptedDigestOid; 494 AssertMsgFailed(("enc=%s hash=%s\n", pszEncryptionOid, pszDigestOid)); 495 } 496 else 497 { 498 /* No, it's a combined one. */ 499 for (size_t i = 0; i < cCombinations; i++) 500 if (!strcmp(pszDigestOid, paCombinations[i].pszEncryptedDigestOid)) 501 return paCombinations[i].pszEncryptedDigestOid; 502 AssertMsgFailed(("enc=%s hash+enc=%s\n", pszEncryptionOid, pszDigestOid)); 503 } 504 } 505 /* The digest OID purely a digest? */ 506 else if (pDigest->idxEncryption == IDX_ENCRYPTION_NIL) 507 { 508 /* Check that it's for the same hash before returning it. */ 509 Assert(pEncrypt->enmDigestType != RTDIGESTTYPE_INVALID); 510 if (pEncrypt->enmDigestType == pDigest->enmDigestType) 511 return pEncrypt->pszSignatureOid; 512 AssertMsgFailed(("enc+hash=%s hash=%s\n", pszEncryptionOid, pszDigestOid)); 513 } 514 /* Both the digest and encryption OIDs are combined ones, so they have to 515 be the same entry then or they cannot be combined. */ 516 else if (pDigest == pEncrypt) 517 return pEncrypt->pszSignatureOid; 518 else 519 AssertMsgFailed(("enc+hash=%s hash+enc=%s\n", pszEncryptionOid, pszDigestOid)); 520 304 521 return NULL; 305 522 } … … 311 528 return RTCrX509AlgorithmIdentifier_CombineEncryptionOidAndDigestOid(pEncryption->Algorithm.szObjId, 312 529 pDigest->Algorithm.szObjId); 530 } 531 532 533 RTDECL(const char *) RTCrX509AlgorithmIdentifier_GetEncryptionOid(PCRTCRX509ALGORITHMIDENTIFIER pThis, bool fMustIncludeHash) 534 { 535 AssertPtrReturn(pThis, NULL); 536 PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pInfo = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pThis->Algorithm.szObjId); 537 if (pInfo && (!fMustIncludeHash || pInfo->enmDigestType != RTDIGESTTYPE_INVALID)) 538 return g_apszEncryptionOids[pInfo->idxEncryption]; 539 return NULL; 540 } 541 542 543 RTDECL(const char *) RTCrX509AlgorithmIdentifier_GetEncryptionOidFromOid(const char *pszAlgorithmOid, bool fMustIncludeHash) 544 { 545 AssertPtrReturn(pszAlgorithmOid, NULL); 546 PCRTCRX509ALGORITHIDENTIFIERINTERNALINFO const pInfo = rtCrX509AlgorithmIdentifier_LookupInfoByOid(pszAlgorithmOid); 547 if (pInfo && (!fMustIncludeHash || pInfo->enmDigestType != RTDIGESTTYPE_INVALID)) 548 return g_apszEncryptionOids[pInfo->idxEncryption]; 549 return NULL; 313 550 } 314 551
Note:
See TracChangeset
for help on using the changeset viewer.