Changeset 64883 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Dec 15, 2016 3:26:20 PM (8 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/asn1/asn1-basics.cpp
r62564 r64883 75 75 76 76 77 78 RTDECL(int) RTAsn1MemGrowArray(PRTASN1ALLOCATION pAllocation, void **ppvArray, size_t cbEntry, 79 uint32_t cCurrent, uint32_t cNew) 77 RTDECL(int) RTAsn1MemResizeArray(PRTASN1ARRAYALLOCATION pAllocation, void ***ppapvArray, uint32_t cCurrent, uint32_t cNew) 80 78 { 81 79 AssertReturn(pAllocation->pAllocator != NULL, VERR_WRONG_ORDER); 82 AssertReturn(cbEntry > 0, VERR_INVALID_PARAMETER); 83 AssertReturn(cNew > cCurrent, VERR_INVALID_PARAMETER); 80 AssertReturn(pAllocation->cbEntry > 0, VERR_WRONG_ORDER); 81 AssertReturn(cCurrent <= pAllocation->cEntriesAllocated, VERR_INVALID_PARAMETER); 82 AssertReturn(cCurrent <= pAllocation->cPointersAllocated, VERR_INVALID_PARAMETER); 84 83 AssertReturn(cNew < _1M, VERR_OUT_OF_RANGE); 85 86 pAllocation->cReallocs++; 87 88 void *pvOld = *ppvArray; 89 90 /* Initial allocation? */ 91 if (cCurrent == 0) 92 { 93 AssertReturn(pvOld == NULL, VERR_INVALID_PARAMETER); 94 AssertReturn(cNew != 0, VERR_INVALID_PARAMETER); 95 return pAllocation->pAllocator->pfnAlloc(pAllocation->pAllocator, pAllocation, ppvArray, cNew * cbEntry); 96 } 97 98 /* Do we need to grow the allocation or did we already allocate sufficient memory in a previous call? */ 99 size_t cbNew = cNew * cbEntry; 100 if (pAllocation->cbAllocated < cbNew) 101 { 102 /* Need to grow. Adjust the new size according to how many times we've been called. */ 103 if (pAllocation->cReallocs > 2) 104 { 105 if (pAllocation->cReallocs > 8) 106 cNew += 8; 107 else if (pAllocation->cReallocs < 4) 108 cNew += 2; 109 else 110 cNew += 4; 111 cbNew += cNew * cbEntry; 112 } 113 114 int rc = pAllocation->pAllocator->pfnRealloc(pAllocation->pAllocator, pAllocation, pvOld, ppvArray, cbNew); 115 if (RT_FAILURE(rc)) 116 return rc; 117 Assert(pAllocation->cbAllocated >= cbNew); 118 119 /* Clear the memory. */ 120 size_t cbOld = cCurrent * cbEntry; 121 RT_BZERO((uint8_t *)*ppvArray + cbOld, pAllocation->cbAllocated - cbOld); 122 } 123 124 return VINF_SUCCESS; 84 Assert(pAllocation->cEntriesAllocated <= pAllocation->cPointersAllocated); 85 86 /* 87 * Is there sufficent space allocated already? 88 * 89 * We keep unused entires ZEROed, therefore we must always call the allocator 90 * when shrinking (this also helps with the electric fence allocator). 91 */ 92 if (cNew <= pAllocation->cEntriesAllocated) 93 { 94 if (cCurrent <= cNew) 95 return VINF_SUCCESS; 96 pAllocation->pAllocator->pfnShrinkArray(pAllocation->pAllocator, pAllocation, ppapvArray, cCurrent, cNew); 97 return VINF_SUCCESS; 98 } 99 100 /* 101 * Must grow (or do initial alloc). 102 */ 103 pAllocation->cResizeCalls++; 104 return pAllocation->pAllocator->pfnGrowArray(pAllocation->pAllocator, pAllocation, ppapvArray, cNew); 105 } 106 107 108 RTDECL(void) RTAsn1MemFreeArray(PRTASN1ARRAYALLOCATION pAllocation, void **papvArray) 109 { 110 Assert(pAllocation->pAllocator != NULL); 111 if (papvArray) 112 { 113 pAllocation->pAllocator->pfnFreeArray(pAllocation->pAllocator, pAllocation, papvArray); 114 Assert(pAllocation->cPointersAllocated == 0); 115 Assert(pAllocation->cEntriesAllocated == 0); 116 } 125 117 } 126 118 … … 171 163 pAllocation->uReserved0 = 0; 172 164 pAllocation->pAllocator = pAllocator; 165 return pAllocation; 166 } 167 168 169 RTDECL(PRTASN1ARRAYALLOCATION) RTAsn1MemInitArrayAllocation(PRTASN1ARRAYALLOCATION pAllocation, 170 PCRTASN1ALLOCATORVTABLE pAllocator, size_t cbEntry) 171 { 172 Assert(cbEntry >= sizeof(RTASN1CORE)); 173 Assert(cbEntry < _1M); 174 Assert(RT_ALIGN_Z(cbEntry, sizeof(void *)) == cbEntry); 175 pAllocation->cbEntry = (uint32_t)cbEntry; 176 pAllocation->cPointersAllocated = 0; 177 pAllocation->cEntriesAllocated = 0; 178 pAllocation->cResizeCalls = 0; 179 pAllocation->uReserved0 = 0; 180 pAllocation->pAllocator = pAllocator; 173 181 return pAllocation; 174 182 } -
trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp
r63451 r64883 202 202 pAllocation->uReserved0 = 0; 203 203 pAllocation->pAllocator = pCursor->pPrimary->pAllocator; 204 return pAllocation; 205 } 206 207 208 RTDECL(PRTASN1ARRAYALLOCATION) RTAsn1CursorInitArrayAllocation(PRTASN1CURSOR pCursor, PRTASN1ARRAYALLOCATION pAllocation, 209 size_t cbEntry) 210 { 211 Assert(cbEntry >= sizeof(RTASN1CORE)); 212 Assert(cbEntry < _1M); 213 Assert(RT_ALIGN_Z(cbEntry, sizeof(void *)) == cbEntry); 214 pAllocation->cbEntry = (uint32_t)cbEntry; 215 pAllocation->cPointersAllocated = 0; 216 pAllocation->cEntriesAllocated = 0; 217 pAllocation->cResizeCalls = 0; 218 pAllocation->uReserved0 = 0; 219 pAllocation->pAllocator = pCursor->pPrimary->pAllocator; 204 220 return pAllocation; 205 221 } -
trunk/src/VBox/Runtime/common/asn1/asn1-default-allocator.cpp
r62564 r64883 100 100 101 101 102 /** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnFreeArray} */ 103 static DECLCALLBACK(void) rtAsn1DefaultAllocator_FreeArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation, 104 void **papvArray) 105 { 106 RT_NOREF_PV(pThis); 107 Assert(papvArray); 108 Assert(pAllocation->cbEntry); 109 110 uint32_t i = pAllocation->cEntriesAllocated; 111 while (i-- > 0) 112 RTMemFree(papvArray[i]); 113 RTMemFree(papvArray); 114 115 pAllocation->cEntriesAllocated = 0; 116 pAllocation->cPointersAllocated = 0; 117 } 118 119 120 /** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnGrowArray} */ 121 static DECLCALLBACK(int) rtAsn1DefaultAllocator_GrowArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation, 122 void ***ppapvArray, uint32_t cMinEntries) 123 { 124 RT_NOREF_PV(pThis); 125 126 /* 127 * Resize the pointer array. We do chunks of 64 bytes for now. 128 */ 129 void **papvArray = *ppapvArray; 130 uint32_t cPointers = RT_ALIGN_32(cMinEntries, 64 / sizeof(void *)); 131 if (cPointers > pAllocation->cPointersAllocated) 132 { 133 void *pvPointers = RTMemRealloc(papvArray, cPointers * sizeof(void *)); 134 if (pvPointers) 135 { /* likely */ } 136 else if (cMinEntries > pAllocation->cPointersAllocated) 137 { 138 cPointers = cMinEntries; 139 pvPointers = RTMemRealloc(*ppapvArray, cPointers * sizeof(void *)); 140 if (!pvPointers) 141 return VERR_NO_MEMORY; 142 } 143 else 144 { 145 cPointers = pAllocation->cPointersAllocated; 146 pvPointers = papvArray; 147 } 148 149 *ppapvArray = papvArray = (void **)pvPointers; 150 RT_BZERO(&papvArray[pAllocation->cPointersAllocated], (cPointers - pAllocation->cPointersAllocated) * sizeof(void *)); 151 pAllocation->cPointersAllocated = cPointers; 152 } 153 154 /* 155 * Add more entries. Do multiple as the array grows. 156 * 157 * Note! We could possibly optimize this by allocating slabs of entries and 158 * slice them up. However, keep things as simple as possible for now. 159 */ 160 uint32_t cEntries = cMinEntries; 161 if (cEntries > 2) 162 { 163 if (cEntries > 8) 164 cEntries = RT_ALIGN_32(cEntries, 4); 165 else 166 cEntries = RT_ALIGN_32(cEntries, 2); 167 cEntries = RT_MIN(cEntries, cPointers); 168 Assert(cEntries >= cMinEntries); 169 } 170 Assert(cEntries <= pAllocation->cPointersAllocated); 171 172 while (pAllocation->cEntriesAllocated < cEntries) 173 { 174 void *pv; 175 papvArray[pAllocation->cEntriesAllocated] = pv = RTMemAllocZ(pAllocation->cbEntry); 176 if (pv) 177 pAllocation->cEntriesAllocated++; 178 else if (pAllocation->cEntriesAllocated >= cMinEntries) 179 break; 180 else 181 return VERR_NO_MEMORY; 182 } 183 184 return VINF_SUCCESS; 185 } 186 187 188 /** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnShrinkArray} */ 189 static DECLCALLBACK(void) rtAsn1DefaultAllocator_ShrinkArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation, 190 void ***ppapvArray, uint32_t cNew, uint32_t cCurrent) 191 { 192 RT_NOREF_PV(pThis); 193 194 /* 195 * For now we only zero the entries being removed. 196 */ 197 void **papvArray = *ppapvArray; 198 while (cNew < cCurrent) 199 { 200 RT_BZERO(papvArray[cNew], pAllocation->cbEntry); 201 cNew++; 202 } 203 } 204 205 206 102 207 /** The default ASN.1 allocator. */ 208 #if 1 || !defined(IN_RING3) || defined(DOXYGEN_RUNNING) 103 209 RT_DECL_DATA_CONST(RTASN1ALLOCATORVTABLE const) g_RTAsn1DefaultAllocator = 210 #else 211 RT_DECL_DATA_CONST(RTASN1ALLOCATORVTABLE const) g_RTAsn1DefaultAllocatorDisabled = 212 #endif 104 213 { 105 214 rtAsn1DefaultAllocator_Free, 106 215 rtAsn1DefaultAllocator_Alloc, 107 rtAsn1DefaultAllocator_Realloc 216 rtAsn1DefaultAllocator_Realloc, 217 rtAsn1DefaultAllocator_FreeArray, 218 rtAsn1DefaultAllocator_GrowArray, 219 rtAsn1DefaultAllocator_ShrinkArray 108 220 }; 109 221 -
trunk/src/VBox/Runtime/common/asn1/asn1-efence-allocator.cpp
r62564 r64883 80 80 81 81 82 /** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnFreeArray} */ 83 static DECLCALLBACK(void) rtAsn1EFenceAllocator_FreeArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation, 84 void **papvArray) 85 { 86 RT_NOREF_PV(pThis); 87 Assert(papvArray); 88 Assert(pAllocation->cbEntry); 89 Assert(pAllocation->cEntriesAllocated <= pAllocation->cPointersAllocated); 90 91 uint32_t i = pAllocation->cEntriesAllocated; 92 while (i-- > 0) 93 { 94 RTMemEfFreeNP(papvArray[i]); 95 papvArray[i] = NULL; 96 } 97 RTMemEfFreeNP(papvArray); 98 99 pAllocation->cEntriesAllocated = 0; 100 pAllocation->cPointersAllocated = 0; 101 } 102 103 104 /** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnGrowArray} */ 105 static DECLCALLBACK(int) rtAsn1EFenceAllocator_GrowArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation, 106 void ***ppapvArray, uint32_t cMinEntries) 107 { 108 RT_NOREF_PV(pThis); 109 Assert(pAllocation->cbEntry); 110 Assert(pAllocation->cEntriesAllocated <= pAllocation->cPointersAllocated); 111 112 /* 113 * Resize the pointer array. 114 */ 115 void **papvArray = *ppapvArray; 116 void *pvPointers = RTMemEfReallocNP(papvArray, cMinEntries * sizeof(void *), RTMEM_TAG); 117 if (pvPointers) 118 { 119 *ppapvArray = papvArray = (void **)pvPointers; 120 if (cMinEntries > pAllocation->cPointersAllocated) /* possible on multiple shrink failures */ 121 RT_BZERO(&papvArray[pAllocation->cPointersAllocated], 122 (cMinEntries - pAllocation->cPointersAllocated) * sizeof(void *)); 123 else 124 AssertFailed(); 125 pAllocation->cPointersAllocated = cMinEntries; 126 } 127 else if (cMinEntries > pAllocation->cPointersAllocated) 128 return VERR_NO_MEMORY; 129 /* else: possible but unlikely */ 130 131 /* 132 * Add more entries. 133 */ 134 while (pAllocation->cEntriesAllocated < cMinEntries) 135 { 136 void *pv; 137 papvArray[pAllocation->cEntriesAllocated] = pv = RTMemEfAllocZNP(pAllocation->cbEntry, RTMEM_TAG); 138 if (pv) 139 pAllocation->cEntriesAllocated++; 140 else 141 return VERR_NO_MEMORY; 142 } 143 144 return VINF_SUCCESS; 145 } 146 147 148 /** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnShrinkArray} */ 149 static DECLCALLBACK(void) rtAsn1EFenceAllocator_ShrinkArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation, 150 void ***ppapvArray, uint32_t cNew, uint32_t cCurrent) 151 { 152 RT_NOREF_PV(pThis); 153 Assert(pAllocation->cbEntry); 154 Assert(pAllocation->cEntriesAllocated <= pAllocation->cPointersAllocated); 155 156 /* 157 * We always free and resize. 158 */ 159 Assert(pAllocation->cEntriesAllocated == cCurrent); 160 Assert(cNew < cCurrent); 161 162 /* Free entries. */ 163 void **papvArray = *ppapvArray; 164 while (cCurrent-- > cNew) 165 { 166 RTMemEfFreeNP(papvArray[cCurrent]); 167 papvArray[cCurrent] = NULL; 168 } 169 pAllocation->cEntriesAllocated = cNew; 170 171 /* Try resize pointer array. Failure here is a genuine possibility since the 172 efence code will try allocate a new block. This causes extra fun in the 173 grow method above. */ 174 void *pvPointers = RTMemEfReallocNP(papvArray, cNew * sizeof(void *), RTMEM_TAG); 175 if (pvPointers) 176 { 177 *ppapvArray = (void **)pvPointers; 178 pAllocation->cPointersAllocated = cNew; 179 } 180 } 181 182 82 183 /** The Electric Fence ASN.1 allocator. */ 83 184 RT_DECL_DATA_CONST(RTASN1ALLOCATORVTABLE const) g_RTAsn1EFenceAllocator = … … 85 186 rtAsn1EFenceAllocator_Free, 86 187 rtAsn1EFenceAllocator_Alloc, 87 rtAsn1EFenceAllocator_Realloc 188 rtAsn1EFenceAllocator_Realloc, 189 rtAsn1EFenceAllocator_FreeArray, 190 rtAsn1EFenceAllocator_GrowArray, 191 rtAsn1EFenceAllocator_ShrinkArray 88 192 }; 89 193 194 #if 0 && defined(IN_RING3) /* for efence testing */ 195 RT_DECL_DATA_CONST(RTASN1ALLOCATORVTABLE const) g_RTAsn1DefaultAllocator = 196 { 197 rtAsn1EFenceAllocator_Free, 198 rtAsn1EFenceAllocator_Alloc, 199 rtAsn1EFenceAllocator_Realloc, 200 rtAsn1EFenceAllocator_FreeArray, 201 rtAsn1EFenceAllocator_GrowArray, 202 rtAsn1EFenceAllocator_ShrinkArray 203 }; 204 #endif 205 -
trunk/src/VBox/Runtime/common/crypto/pkcs7-core.cpp
r62477 r64883 49 49 * Note! We ASSUME a single signing time attribute, which simplifies the interface. 50 50 */ 51 uint32_t cAttrsLeft;52 P CRTCRPKCS7ATTRIBUTEpAttr;51 uint32_t cAttrsLeft; 52 PRTCRPKCS7ATTRIBUTE const *ppAttr; 53 53 if (!ppSignerInfo || *ppSignerInfo == NULL) 54 54 { 55 55 cAttrsLeft = pThis->AuthenticatedAttributes.cItems; 56 p Attr = pThis->AuthenticatedAttributes.paItems;56 ppAttr = pThis->AuthenticatedAttributes.papItems; 57 57 while (cAttrsLeft-- > 0) 58 58 { 59 PCRTCRPKCS7ATTRIBUTE pAttr = *ppAttr; 59 60 if ( pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME 60 61 && pAttr->uValues.pSigningTime->cItems > 0) … … 62 63 if (ppSignerInfo) 63 64 *ppSignerInfo = pThis; 64 return &pAttr->uValues.pSigningTime->paItems[0];65 return pAttr->uValues.pSigningTime->papItems[0]; 65 66 } 66 p Attr++;67 ppAttr++; 67 68 } 68 69 } … … 74 75 */ 75 76 cAttrsLeft = pThis->UnauthenticatedAttributes.cItems; 76 p Attr = pThis->UnauthenticatedAttributes.paItems;77 ppAttr = pThis->UnauthenticatedAttributes.papItems; 77 78 while (cAttrsLeft-- > 0) 78 79 { 80 PCRTCRPKCS7ATTRIBUTE pAttr = *ppAttr; 79 81 if (pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_COUNTER_SIGNATURES) 80 82 { 81 uint32_t cSignatures = pAttr->uValues.pCounterSignatures->cItems;82 P CRTCRPKCS7SIGNERINFO pSignature = pAttr->uValues.pCounterSignatures->paItems;83 uint32_t cSignatures = pAttr->uValues.pCounterSignatures->cItems; 84 PRTCRPKCS7SIGNERINFO *ppSignature = pAttr->uValues.pCounterSignatures->papItems; 83 85 84 86 /* Skip past the previous counter signature. */ … … 87 89 { 88 90 cSignatures--; 89 if ( pSignature == *ppSignerInfo)91 if (*ppSignature == *ppSignerInfo) 90 92 { 91 93 *ppSignerInfo = NULL; 92 p Signature++;94 ppSignature++; 93 95 break; 94 96 } 95 p Signature++;97 ppSignature++; 96 98 } 97 99 … … 99 101 while (cSignatures-- > 0) 100 102 { 101 uint32_t cCounterAttrsLeft = pSignature->AuthenticatedAttributes.cItems; 102 PCRTCRPKCS7ATTRIBUTE pCounterAttr = pSignature->AuthenticatedAttributes.paItems; 103 PCRTCRPKCS7SIGNERINFO pSignature = *ppSignature; 104 uint32_t cCounterAttrsLeft = pSignature->AuthenticatedAttributes.cItems; 105 PRTCRPKCS7ATTRIBUTE const *ppCounterAttr = pSignature->AuthenticatedAttributes.papItems; 103 106 while (cCounterAttrsLeft-- > 0) 104 107 { 108 PCRTCRPKCS7ATTRIBUTE pCounterAttr = *ppCounterAttr; 105 109 if ( pCounterAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME 106 110 && pCounterAttr->uValues.pSigningTime->cItems > 0) … … 108 112 if (ppSignerInfo) 109 113 *ppSignerInfo = pSignature; 110 return &pCounterAttr->uValues.pSigningTime->paItems[0];114 return pCounterAttr->uValues.pSigningTime->papItems[0]; 111 115 } 112 p CounterAttr++;116 ppCounterAttr++; 113 117 } 114 p Signature++;118 ppSignature++; 115 119 } 116 120 } 117 p Attr++;121 ppAttr++; 118 122 } 119 123 … … 128 132 129 133 130 RTDECL(PCRTASN1TIME) RTCrPkcs7SignerInfo_GetMsTimestamp(PCRTCRPKCS7SIGNERINFO pThis, PCRTCRPKCS7CONTENTINFO *ppContentInfo )134 RTDECL(PCRTASN1TIME) RTCrPkcs7SignerInfo_GetMsTimestamp(PCRTCRPKCS7SIGNERINFO pThis, PCRTCRPKCS7CONTENTINFO *ppContentInfoRet) 131 135 { 132 136 /* 133 137 * Assume there is only one, so no need to enumerate anything here. 134 138 */ 135 uint32_t cAttrsLeft= pThis->UnauthenticatedAttributes.cItems;136 P CRTCRPKCS7ATTRIBUTE pAttr = pThis->UnauthenticatedAttributes.paItems;139 uint32_t cAttrsLeft = pThis->UnauthenticatedAttributes.cItems; 140 PRTCRPKCS7ATTRIBUTE const *ppAttr = pThis->UnauthenticatedAttributes.papItems; 137 141 while (cAttrsLeft-- > 0) 138 142 { 143 PCRTCRPKCS7ATTRIBUTE pAttr = *ppAttr; 139 144 if (pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_MS_TIMESTAMP) 140 145 { 141 uint32_t cLeft= pAttr->uValues.pContentInfos->cItems;142 P CRTCRPKCS7CONTENTINFO pContentInfo = &pAttr->uValues.pContentInfos->paItems[0];146 uint32_t cLeft = pAttr->uValues.pContentInfos->cItems; 147 PRTCRPKCS7CONTENTINFO const *ppContentInfo = pAttr->uValues.pContentInfos->papItems; 143 148 while (cLeft-- > 0) 144 149 { 150 PCRTCRPKCS7CONTENTINFO pContentInfo = *ppContentInfo; 145 151 if (RTAsn1ObjId_CompareWithString(&pContentInfo->ContentType, RTCRPKCS7SIGNEDDATA_OID) == 0) 146 152 { … … 148 154 RTCRTSPTSTINFO_OID) == 0) 149 155 { 150 if (ppContentInfo )151 *ppContentInfo = pContentInfo;156 if (ppContentInfoRet) 157 *ppContentInfoRet = pContentInfo; 152 158 return &pContentInfo->u.pSignedData->ContentInfo.u.pTstInfo->GenTime; 153 159 } … … 157 163 } 158 164 } 159 p Attr++;165 ppAttr++; 160 166 } 161 167 … … 163 169 * No signature was found. 164 170 */ 165 if (ppContentInfo )166 *ppContentInfo = NULL;171 if (ppContentInfoRet) 172 *ppContentInfoRet = NULL; 167 173 168 174 return NULL; … … 189 195 { 190 196 for (uint32_t i = 0; i < pCertificates->cItems; i++) 191 if ( pCertificates->paItems[i].enmChoice == RTCRPKCS7CERTCHOICE_X509 192 && RTCrX509Certificate_MatchIssuerAndSerialNumber(pCertificates->paItems[i].u.pX509Cert, pIssuer, pSerialNumber)) 193 return pCertificates->paItems[i].u.pX509Cert; 197 { 198 PCRTCRPKCS7CERT pCert = pCertificates->papItems[i]; 199 if ( pCert->enmChoice == RTCRPKCS7CERTCHOICE_X509 200 && RTCrX509Certificate_MatchIssuerAndSerialNumber(pCert->u.pX509Cert, pIssuer, pSerialNumber)) 201 return pCert->u.pX509Cert; 202 } 194 203 return NULL; 195 204 } -
trunk/src/VBox/Runtime/common/crypto/pkcs7-sanity.cpp
r62564 r64883 68 68 for (uint32_t i = 0; i < pSignedData->DigestAlgorithms.cItems; i++) 69 69 { 70 if (RTCrX509AlgorithmIdentifier_QueryDigestType( &pSignedData->DigestAlgorithms.paItems[i]) == RTDIGESTTYPE_INVALID)70 if (RTCrX509AlgorithmIdentifier_QueryDigestType(pSignedData->DigestAlgorithms.papItems[i]) == RTDIGESTTYPE_INVALID) 71 71 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_UNKNOWN_DIGEST_ALGORITHM, 72 72 "%s: SignedData.DigestAlgorithms[%i] is not known: %s", 73 pszErrorTag, i, pSignedData->DigestAlgorithms.pa Items[i].Algorithm.szObjId);74 if (pSignedData->DigestAlgorithms.pa Items[i].Parameters.enmType != RTASN1TYPE_NULL)73 pszErrorTag, i, pSignedData->DigestAlgorithms.papItems[i]->Algorithm.szObjId); 74 if (pSignedData->DigestAlgorithms.papItems[i]->Parameters.enmType != RTASN1TYPE_NULL) 75 75 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_DIGEST_PARAMS_NOT_IMPL, 76 76 "%s: SignedData.DigestAlgorithms[%i] has parameters: tag=%u", 77 pszErrorTag, i, pSignedData->DigestAlgorithms.pa Items[i].Parameters.u.Core.uTag);77 pszErrorTag, i, pSignedData->DigestAlgorithms.papItems[i]->Parameters.u.Core.uTag); 78 78 } 79 79 … … 106 106 for (uint32_t i = 0; i < pSignedData->SignerInfos.cItems; i++) 107 107 { 108 PCRTCRPKCS7SIGNERINFO pSignerInfo = &pSignedData->SignerInfos.paItems[i];108 PCRTCRPKCS7SIGNERINFO pSignerInfo = pSignedData->SignerInfos.papItems[i]; 109 109 110 110 if (RTAsn1Integer_UnsignedCompareWithU32(&pSignerInfo->Version, RTCRPKCS7SIGNERINFO_V1) != 0) … … 136 136 uint32_t j = 0; 137 137 while ( j < pSignedData->DigestAlgorithms.cItems 138 && RTCrX509AlgorithmIdentifier_Compare( &pSignedData->DigestAlgorithms.paItems[j],138 && RTCrX509AlgorithmIdentifier_Compare(pSignedData->DigestAlgorithms.papItems[j], 139 139 &pSignerInfo->DigestAlgorithm) != 0) 140 140 j++; … … 162 162 for (j = 0; j < pSignerInfo->AuthenticatedAttributes.cItems; j++) 163 163 { 164 PCRTCRPKCS7ATTRIBUTE pAttrib = &pSignerInfo->AuthenticatedAttributes.paItems[j];164 PCRTCRPKCS7ATTRIBUTE pAttrib = pSignerInfo->AuthenticatedAttributes.papItems[j]; 165 165 if (RTAsn1ObjId_CompareWithString(&pAttrib->Type, RTCR_PKCS9_ID_CONTENT_TYPE_OID) == 0) 166 166 { -
trunk/src/VBox/Runtime/common/crypto/pkcs7-verify.cpp
r64531 r64883 75 75 PCRTCRPKCS7SETOFCERTS pCerts = &pContentInfo->u.pSignedData->Certificates; 76 76 for (uint32_t i = 0; i < pCerts->cItems; i++) 77 if (pCerts->pa Items[i].enmChoice == RTCRPKCS7CERTCHOICE_X509)78 rtCrOpenSslAddX509CertToStack(pAddCerts, pCerts->pa Items[i].u.pX509Cert);77 if (pCerts->papItems[i]->enmChoice == RTCRPKCS7CERTCHOICE_X509) 78 rtCrOpenSslAddX509CertToStack(pAddCerts, pCerts->papItems[i]->u.pX509Cert); 79 79 80 80 … … 238 238 while (i-- > 0) 239 239 { 240 PCRTCRPKCS7ATTRIBUTE pAttrib = &pSignerInfo->AuthenticatedAttributes.paItems[i];240 PCRTCRPKCS7ATTRIBUTE pAttrib = pSignerInfo->AuthenticatedAttributes.papItems[i]; 241 241 242 242 if (RTAsn1ObjId_CompareWithString(&pAttrib->Type, RTCR_PKCS9_ID_CONTENT_TYPE_OID) == 0) … … 247 247 248 248 if ( !(fFlags & RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE) /* See note about microsoft below. */ 249 && RTAsn1ObjId_Compare( &pAttrib->uValues.pObjIds->paItems[0], &pSignedData->ContentInfo.ContentType) != 0)249 && RTAsn1ObjId_Compare(pAttrib->uValues.pObjIds->papItems[0], &pSignedData->ContentInfo.ContentType) != 0) 250 250 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_CONTENT_TYPE_ATTRIB_MISMATCH, 251 "Expected content-type %s, found %s", 252 &pAttrib->uValues.pObjIds->paItems[0],pSignedData->ContentInfo.ContentType.szObjId);251 "Expected content-type %s, found %s", pAttrib->uValues.pObjIds->papItems[0]->szObjId, 252 pSignedData->ContentInfo.ContentType.szObjId); 253 253 cContentTypes++; 254 254 } … … 260 260 261 261 if (!RTCrDigestMatch(*phDigest, 262 pAttrib->uValues.pOctetStrings->pa Items[0].Asn1Core.uData.pv,263 pAttrib->uValues.pOctetStrings->pa Items[0].Asn1Core.cb))262 pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.uData.pv, 263 pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.cb)) 264 264 { 265 265 size_t cbHash = RTCrDigestGetHashSize(*phDigest); 266 if (cbHash != pAttrib->uValues.pOctetStrings->pa Items[0].Asn1Core.cb)266 if (cbHash != pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.cb) 267 267 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_MESSAGE_DIGEST_ATTRIB_MISMATCH, 268 268 "Authenticated message-digest attribute mismatch: cbHash=%#zx cbValue=%#x", 269 cbHash, pAttrib->uValues.pOctetStrings->pa Items[0].Asn1Core.cb);269 cbHash, pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.cb); 270 270 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_MESSAGE_DIGEST_ATTRIB_MISMATCH, 271 271 "Authenticated message-digest attribute mismatch (cbHash=%#zx):\n" … … 273 273 "our: %.*Rhxs\n", 274 274 cbHash, 275 cbHash, pAttrib->uValues.pOctetStrings->pa Items[0].Asn1Core.uData.pv,275 cbHash, pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.uData.pv, 276 276 cbHash, RTCrDigestGetHash(*phDigest)); 277 277 } … … 342 342 uint32_t iDigest = pSignedData->DigestAlgorithms.cItems; 343 343 while (iDigest-- > 0) 344 if (RTCrX509AlgorithmIdentifier_Compare( &pSignedData->DigestAlgorithms.paItems[iDigest],344 if (RTCrX509AlgorithmIdentifier_Compare(pSignedData->DigestAlgorithms.papItems[iDigest], 345 345 &pSignerInfo->DigestAlgorithm) == 0) 346 346 { … … 620 620 for (i = 0; i < cDigests; i++) 621 621 { 622 rc = RTCrDigestCreateByObjId(&ahDigests[i], &pSignedData->DigestAlgorithms.pa Items[i].Algorithm);622 rc = RTCrDigestCreateByObjId(&ahDigests[i], &pSignedData->DigestAlgorithms.papItems[i]->Algorithm); 623 623 if (RT_FAILURE(rc)) 624 624 { 625 625 rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_DIGEST_CREATE_ERROR, "Error creating digest for '%s': %Rrc", 626 pSignedData->DigestAlgorithms.pa Items[i].Algorithm.szObjId, rc);626 pSignedData->DigestAlgorithms.papItems[i]->Algorithm.szObjId, rc); 627 627 break; 628 628 } … … 647 647 for (i = 0; i < pSignedData->SignerInfos.cItems; i++) 648 648 { 649 PCRTCRPKCS7SIGNERINFO pSignerInfo = &pSignedData->SignerInfos.paItems[i];649 PCRTCRPKCS7SIGNERINFO pSignerInfo = pSignedData->SignerInfos.papItems[i]; 650 650 RTCRDIGEST hThisDigest = NIL_RTCRDIGEST; /* (gcc maybe incredible stupid.) */ 651 651 rc = rtCrPkcs7VerifyFindDigest(&hThisDigest, pSignedData, pSignerInfo, ahDigests, pErrInfo); -
trunk/src/VBox/Runtime/common/crypto/spc-core.cpp
r62477 r64883 69 69 if (pData) 70 70 for (uint32_t i = 0; i < pData->cItems; i++) 71 if (pData->pa Items[i].enmType == enmType)72 return &pData->paItems[i];71 if (pData->papItems[i]->enmType == enmType) 72 return pData->papItems[i]; 73 73 } 74 74 } -
trunk/src/VBox/Runtime/common/crypto/spc-sanity.cpp
r62477 r64883 57 57 58 58 if (RTCrX509AlgorithmIdentifier_Compare(&pIndData->DigestInfo.DigestAlgorithm, /** @todo not entirely sure about this check... */ 59 &pSignedData->SignerInfos.pa Items[0].DigestAlgorithm) != 0)59 &pSignedData->SignerInfos.papItems[0]->DigestAlgorithm) != 0) 60 60 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_SIGNED_IND_DATA_DIGEST_ALGO_MISMATCH, 61 61 "SpcIndirectDataContent DigestInfo and SignerInfos algorithms mismatch: %s vs %s", 62 62 pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId, 63 pSignedData->SignerInfos.pa Items[0].DigestAlgorithm.Algorithm.szObjId);63 pSignedData->SignerInfos.papItems[0]->DigestAlgorithm.Algorithm.szObjId); 64 64 65 65 if (RTCrX509AlgorithmIdentifier_Compare(&pIndData->DigestInfo.DigestAlgorithm, 66 &pSignedData->DigestAlgorithms.paItems[0]) != 0)66 pSignedData->DigestAlgorithms.papItems[0]) != 0) 67 67 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_IND_DATA_DIGEST_ALGO_NOT_IN_DIGEST_ALGOS, 68 68 "SpcIndirectDataContent DigestInfo and SignedData.DigestAlgorithms[0] mismatch: %s vs %s", 69 69 pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId, 70 pSignedData->DigestAlgorithms.pa Items[0].Algorithm.szObjId);70 pSignedData->DigestAlgorithms.papItems[0]->Algorithm.szObjId); 71 71 72 72 if (fFlags & RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH) … … 126 126 for (uint32_t i = 0; i < pObj->u.pData->cItems; i++) 127 127 { 128 PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttr = &pObj->u.pData->paItems[i];128 PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttr = pObj->u.pData->papItems[i]; 129 129 if ( RTAsn1ObjId_CompareWithString(&pAttr->Type, RTCRSPC_PE_IMAGE_HASHES_V1_OID) == 0 130 130 || RTAsn1ObjId_CompareWithString(&pAttr->Type, RTCRSPC_PE_IMAGE_HASHES_V2_OID) == 0 ) -
trunk/src/VBox/Runtime/common/crypto/x509-certpaths.cpp
r64531 r64883 723 723 if (pThis->pUntrustedCertsSet) 724 724 { 725 uint32_t const cCerts= pThis->pUntrustedCertsSet->cItems;726 P CRTCRPKCS7CERT paCerts = pThis->pUntrustedCertsSet->paItems;725 uint32_t const cCerts = pThis->pUntrustedCertsSet->cItems; 726 PRTCRPKCS7CERT const *papCerts = pThis->pUntrustedCertsSet->papItems; 727 727 for (uint32_t i = 0; i < cCerts; i++) 728 if ( paCerts[i].enmChoice == RTCRPKCS7CERTCHOICE_X509 729 && RTCrX509Certificate_MatchSubjectOrAltSubjectByRfc5280(paCerts[i].u.pX509Cert, pIssuer)) 730 rtCrX509CertPathsAddIssuer(pThis, pNode, paCerts[i].u.pX509Cert, NULL, RTCRX509CERTPATHNODE_SRC_UNTRUSTED_SET); 728 { 729 PCRTCRPKCS7CERT pCert = papCerts[i]; 730 if ( pCert->enmChoice == RTCRPKCS7CERTCHOICE_X509 731 && RTCrX509Certificate_MatchSubjectOrAltSubjectByRfc5280(pCert->u.pX509Cert, pIssuer)) 732 rtCrX509CertPathsAddIssuer(pThis, pNode, pCert->u.pX509Cert, NULL, RTCRX509CERTPATHNODE_SRC_UNTRUSTED_SET); 733 } 731 734 } 732 735 } … … 1057 1060 { 1058 1061 for (uint32_t i = 0; i < pName->cItems; i++) 1059 for (uint32_t j = 0; j < pName->paItems[i].cItems; j++) 1060 { 1061 PRTCRX509ATTRIBUTETYPEANDVALUE pAttrib = &pName->paItems[i].paItems[j]; 1062 { 1063 PCRTCRX509RELATIVEDISTINGUISHEDNAME const pRdn = pName->papItems[i]; 1064 for (uint32_t j = 0; j < pRdn->cItems; j++) 1065 { 1066 PRTCRX509ATTRIBUTETYPEANDVALUE pAttrib = pRdn->papItems[j]; 1062 1067 1063 1068 const char *pszType = pAttrib->Type.szObjId; … … 1118 1123 rtDumpPrintf(pfnPrintfV, pvUser, "<not-string: uTag=%#x>", pAttrib->Value.u.Core.uTag); 1119 1124 } 1125 } 1120 1126 } 1121 1127 … … 1350 1356 * @param pThis The validator instance. 1351 1357 * @param cSubtrees The number of sub-trees to add. 1352 * @param paSubtrees Array of sub-trees to add. 1353 */ 1354 static bool rtCrX509CpvAddPermittedSubtrees(PRTCRX509CERTPATHSINT pThis, uint32_t cSubtrees, PCRTCRX509GENERALSUBTREE paSubtrees) 1358 * @param papSubtrees Array of sub-trees to add. 1359 */ 1360 static bool rtCrX509CpvAddPermittedSubtrees(PRTCRX509CERTPATHSINT pThis, uint32_t cSubtrees, 1361 PRTCRX509GENERALSUBTREE const *papSubtrees) 1355 1362 { 1356 1363 /* … … 1375 1382 for (uint32_t iSrc = 0; iSrc < cSubtrees; iSrc++) 1376 1383 { 1377 if (!rtCrX509CpvCheckSubtreeValidity(pThis, &paSubtrees[iSrc]))1384 if (!rtCrX509CpvCheckSubtreeValidity(pThis, papSubtrees[iSrc])) 1378 1385 return false; 1379 pThis->v.papPermittedSubtrees[iDst] = &paSubtrees[iSrc];1386 pThis->v.papPermittedSubtrees[iDst] = papSubtrees[iSrc]; 1380 1387 iDst++; 1381 1388 } … … 1383 1390 1384 1391 return true; 1392 } 1393 1394 1395 /** 1396 * Adds a one permitted sub-tree. 1397 * 1398 * We store reference to each individual sub-tree because we must support 1399 * intersection calculation. 1400 * 1401 * @returns success indiciator. 1402 * @param pThis The validator instance. 1403 * @param pSubtree Array of sub-trees to add. 1404 */ 1405 static bool rtCrX509CpvAddPermittedSubtree(PRTCRX509CERTPATHSINT pThis, PCRTCRX509GENERALSUBTREE pSubtree) 1406 { 1407 return rtCrX509CpvAddPermittedSubtrees(pThis, 1, (PRTCRX509GENERALSUBTREE const *)&pSubtree); 1385 1408 } 1386 1409 … … 1405 1428 } 1406 1429 1407 uint32_t cRight= pSubtrees->cItems;1408 P CRTCRX509GENERALSUBTREE paRight = pSubtrees->paItems;1430 uint32_t cRight = pSubtrees->cItems; 1431 PRTCRX509GENERALSUBTREE const *papRight = pSubtrees->papItems; 1409 1432 if (cRight == 0) 1410 1433 { … … 1417 1440 PCRTCRX509GENERALSUBTREE *papLeft = pThis->v.papPermittedSubtrees; 1418 1441 if (!cLeft) /* first name constraint, no initial constraint */ 1419 return rtCrX509CpvAddPermittedSubtrees(pThis, cRight, pa Right);1442 return rtCrX509CpvAddPermittedSubtrees(pThis, cRight, papRight); 1420 1443 1421 1444 /* … … 1431 1454 for (uint32_t iRight = 0; iRight < cRight; iRight++) 1432 1455 { 1433 if (!rtCrX509CpvCheckSubtreeValidity(pThis, &paRight[iRight]))1456 if (!rtCrX509CpvCheckSubtreeValidity(pThis, papRight[iRight])) 1434 1457 return false; 1435 1458 1436 RTCRX509GENERALNAMECHOICE const enmRightChoice = pa Right[iRight].Base.enmChoice;1459 RTCRX509GENERALNAMECHOICE const enmRightChoice = papRight[iRight]->Base.enmChoice; 1437 1460 afRightTags[enmRightChoice] = true; 1438 1461 … … 1441 1464 if (papLeft[iLeft]->Base.enmChoice == enmRightChoice) 1442 1465 { 1443 if (RTCrX509GeneralSubtree_Compare(papLeft[iLeft], &paRight[iRight]) == 0)1466 if (RTCrX509GeneralSubtree_Compare(papLeft[iLeft], papRight[iRight]) == 0) 1444 1467 { 1445 1468 if (!fHaveRight) 1446 1469 { 1447 1470 fHaveRight = true; 1448 rtCrX509CpvAddPermittedSubtree s(pThis, 1, papLeft[iLeft]);1471 rtCrX509CpvAddPermittedSubtree(pThis, papLeft[iLeft]); 1449 1472 } 1450 1473 } 1451 else if (RTCrX509GeneralSubtree_ConstraintMatch(papLeft[iLeft], &paRight[iRight]))1474 else if (RTCrX509GeneralSubtree_ConstraintMatch(papLeft[iLeft], papRight[iRight])) 1452 1475 { 1453 1476 if (!fHaveRight) 1454 1477 { 1455 1478 fHaveRight = true; 1456 rtCrX509CpvAddPermittedSubtree s(pThis, 1, &paRight[iRight]);1479 rtCrX509CpvAddPermittedSubtree(pThis, papRight[iRight]); 1457 1480 } 1458 1481 } 1459 else if (RTCrX509GeneralSubtree_ConstraintMatch( &paRight[iRight], papLeft[iLeft]))1460 rtCrX509CpvAddPermittedSubtree s(pThis, 1, papLeft[iLeft]);1482 else if (RTCrX509GeneralSubtree_ConstraintMatch(papRight[iRight], papLeft[iLeft])) 1483 rtCrX509CpvAddPermittedSubtree(pThis, papLeft[iLeft]); 1461 1484 } 1462 1485 } … … 1467 1490 for (uint32_t iLeft = 0; iLeft < cLeft; iLeft++) 1468 1491 if (!afRightTags[papLeft[iLeft]->Base.enmChoice]) 1469 rtCrX509CpvAddPermittedSubtree s(pThis, 1, papLeft[iLeft]);1492 rtCrX509CpvAddPermittedSubtree(pThis, papLeft[iLeft]); 1470 1493 1471 1494 /* … … 1541 1564 uint32_t j = pSubTrees->cItems; 1542 1565 while (j-- > 0) 1543 if ( RTCRX509GENERALNAME_IS_DIRECTORY_NAME(&pSubTrees->paItems[j].Base) 1544 && RTCrX509Name_ConstraintMatch(&pSubTrees->paItems[j].Base.u.pT4->DirectoryName, pName)) 1566 { 1567 PCRTCRX509GENERALSUBTREE const pSubTree = pSubTrees->papItems[j]; 1568 if ( RTCRX509GENERALNAME_IS_DIRECTORY_NAME(&pSubTree->Base) 1569 && RTCrX509Name_ConstraintMatch(&pSubTree->Base.u.pT4->DirectoryName, pName)) 1545 1570 return true; 1571 } 1546 1572 } 1547 1573 return false; … … 1566 1592 uint32_t j = pSubTrees->cItems; 1567 1593 while (j-- > 0) 1568 if (RTCrX509GeneralName_ConstraintMatch(&pSubTrees->pa Items[j].Base, pGeneralName))1594 if (RTCrX509GeneralName_ConstraintMatch(&pSubTrees->papItems[j]->Base, pGeneralName)) 1569 1595 return true; 1570 1596 } … … 1951 1977 if (pThis->pInitialPermittedSubtrees) 1952 1978 rtCrX509CpvAddPermittedSubtrees(pThis, pThis->pInitialPermittedSubtrees->cItems, 1953 pThis->pInitialPermittedSubtrees->pa Items);1979 pThis->pInitialPermittedSubtrees->papItems); 1954 1980 if (pThis->pInitialExcludedSubtrees) 1955 1981 rtCrX509CpvAddExcludedSubtrees(pThis, pThis->pInitialExcludedSubtrees); … … 2053 2079 uint32_t i = pAltSubjectName->cItems; 2054 2080 while (i-- > 0) 2055 if ( !rtCrX509CpvIsGeneralNamePermitted(pThis, &pAltSubjectName->paItems[i])2056 || rtCrX509CpvIsGeneralNameExcluded(pThis, &pAltSubjectName->paItems[i]))2081 if ( !rtCrX509CpvIsGeneralNamePermitted(pThis, pAltSubjectName->papItems[i]) 2082 || rtCrX509CpvIsGeneralNameExcluded(pThis, pAltSubjectName->papItems[i])) 2057 2083 return rtCrX509CpvFailed(pThis, VERR_CR_X509_CPV_ALT_NAME_NOT_PERMITTED, 2058 2084 "Alternative name #%u is is not permitted by current name constraints", i); … … 2081 2107 while (i-- > 0) 2082 2108 { 2083 PCRTCRX509POLICYQUALIFIERINFOS const pQualifiers = &pPolicies->pa Items[i].PolicyQualifiers;2084 PCRTASN1OBJID const pIdP = &pPolicies->pa Items[i].PolicyIdentifier;2109 PCRTCRX509POLICYQUALIFIERINFOS const pQualifiers = &pPolicies->papItems[i]->PolicyQualifiers; 2110 PCRTASN1OBJID const pIdP = &pPolicies->papItems[i]->PolicyIdentifier; 2085 2111 if (RTAsn1ObjId_CompareWithString(pIdP, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0) 2086 2112 { … … 2132 2158 || (pNode->pParent && fSelfIssued) ) ) 2133 2159 { 2134 PCRTCRX509POLICYQUALIFIERINFOS pApQ = &pPolicies->pa Items[iAnyPolicy].PolicyQualifiers;2160 PCRTCRX509POLICYQUALIFIERINFOS pApQ = &pPolicies->papItems[iAnyPolicy]->PolicyQualifiers; 2135 2161 RTListForEach(pListAbove, pCur, RTCRX509CERTPATHSPOLICYNODE, DepthEntry) 2136 2162 { … … 2183 2209 while (i-- > 0) 2184 2210 { 2185 if (RTAsn1ObjId_CompareWithString(&pPolicyMappings->paItems[i].IssuerDomainPolicy, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0) 2211 PCRTCRX509POLICYMAPPING const pOne = pPolicyMappings->papItems[i]; 2212 if (RTAsn1ObjId_CompareWithString(&pOne->IssuerDomainPolicy, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0) 2186 2213 return rtCrX509CpvFailed(pThis, VERR_CR_X509_CPV_INVALID_POLICY_MAPPING, 2187 2214 "Invalid policy mapping %#u: IssuerDomainPolicy is anyPolicy.", i); 2188 2215 2189 if (RTAsn1ObjId_CompareWithString(&p PolicyMappings->paItems[i].SubjectDomainPolicy, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0)2216 if (RTAsn1ObjId_CompareWithString(&pOne->SubjectDomainPolicy, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0) 2190 2217 return rtCrX509CpvFailed(pThis, VERR_CR_X509_CPV_INVALID_POLICY_MAPPING, 2191 2218 "Invalid policy mapping %#u: SubjectDomainPolicy is anyPolicy.", i); … … 2201 2228 while (i-- > 0) 2202 2229 { 2230 PCRTCRX509POLICYMAPPING const pOne = pPolicyMappings->papItems[i]; 2231 2203 2232 uint32_t cFound = 0; 2204 2233 RTListForEach(&pThis->v.paValidPolicyDepthLists[iDepth], pCur, RTCRX509CERTPATHSPOLICYNODE, DepthEntry) 2205 2234 { 2206 if (RTAsn1ObjId_Compare(pCur->pValidPolicy, &p PolicyMappings->paItems[i].IssuerDomainPolicy))2235 if (RTAsn1ObjId_Compare(pCur->pValidPolicy, &pOne->IssuerDomainPolicy)) 2207 2236 { 2208 2237 if (!pCur->fAlreadyMapped) 2209 2238 { 2210 2239 pCur->fAlreadyMapped = true; 2211 pCur->pExpectedPolicyFirst = &p PolicyMappings->paItems[i].SubjectDomainPolicy;2240 pCur->pExpectedPolicyFirst = &pOne->SubjectDomainPolicy; 2212 2241 } 2213 2242 else … … 2221 2250 pCur->cMoreExpectedPolicySet, iDepth); 2222 2251 pCur->papMoreExpectedPolicySet = (PCRTASN1OBJID *)pvNew; 2223 pCur->papMoreExpectedPolicySet[iExpected] = &p PolicyMappings->paItems[i].SubjectDomainPolicy;2252 pCur->papMoreExpectedPolicySet[iExpected] = &pOne->SubjectDomainPolicy; 2224 2253 pCur->cMoreExpectedPolicySet = iExpected + 1; 2225 2254 } … … 2238 2267 { 2239 2268 if (!rtCrX509CpvPolicyTreeInsertNew(pThis, pCur->pParent, iDepth, 2240 &p PolicyMappings->paItems[i].IssuerDomainPolicy,2269 &pOne->IssuerDomainPolicy, 2241 2270 pCur->pPolicyQualifiers, 2242 &p PolicyMappings->paItems[i].SubjectDomainPolicy))2271 &pOne->SubjectDomainPolicy)) 2243 2272 return false; 2244 2273 break; … … 2258 2287 while (i-- > 0) 2259 2288 { 2289 PCRTCRX509POLICYMAPPING const pOne = pPolicyMappings->papItems[i]; 2260 2290 RTListForEachSafe(&pThis->v.paValidPolicyDepthLists[iDepth], pCur, pNext, RTCRX509CERTPATHSPOLICYNODE, DepthEntry) 2261 2291 { 2262 if (RTAsn1ObjId_Compare(pCur->pValidPolicy, &p PolicyMappings->paItems[i].IssuerDomainPolicy))2292 if (RTAsn1ObjId_Compare(pCur->pValidPolicy, &pOne->IssuerDomainPolicy)) 2263 2293 { 2264 2294 rtCrX509CpvPolicyTreeDestroyNode(pThis, pCur); … … 2410 2440 static bool rtCrX509CpvCheckCriticalExtensions(PRTCRX509CERTPATHSINT pThis, PRTCRX509CERTPATHNODE pNode) 2411 2441 { 2412 uint32_t cLeft = pNode->pCert->TbsCertificate.T3.Extensions.cItems;2413 P CRTCRX509EXTENSION pCur = pNode->pCert->TbsCertificate.T3.Extensions.paItems;2442 uint32_t cLeft = pNode->pCert->TbsCertificate.T3.Extensions.cItems; 2443 PRTCRX509EXTENSION const *ppCur = pNode->pCert->TbsCertificate.T3.Extensions.papItems; 2414 2444 while (cLeft-- > 0) 2415 2445 { 2446 PCRTCRX509EXTENSION const pCur = *ppCur; 2416 2447 if (pCur->Critical.fValue) 2417 2448 { … … 2431 2462 } 2432 2463 2433 p Cur++;2464 ppCur++; 2434 2465 } 2435 2466 -
trunk/src/VBox/Runtime/common/crypto/x509-core.cpp
r62477 r64883 608 608 for (uint32_t iLeft = 0; iLeft < cItems; iLeft++) 609 609 { 610 PCRTCRX509ATTRIBUTETYPEANDVALUE pLeftAttr = &pLeft->paItems[iLeft];610 PCRTCRX509ATTRIBUTETYPEANDVALUE pLeftAttr = pLeft->papItems[iLeft]; 611 611 bool fFound = false; 612 612 for (uint32_t iRight = 0; iRight < cItems; iRight++) 613 if (RTCrX509AttributeTypeAndValue_MatchAsRdnByRfc5280(pLeftAttr, &pRight->paItems[iRight]))613 if (RTCrX509AttributeTypeAndValue_MatchAsRdnByRfc5280(pLeftAttr, pRight->papItems[iRight])) 614 614 { 615 615 fFound = true; … … 637 637 /* Require exact order. */ 638 638 for (uint32_t iRdn = 0; iRdn < cItems; iRdn++) 639 if (!RTCrX509RelativeDistinguishedName_MatchByRfc5280( &pLeft->paItems[iRdn], &pRight->paItems[iRdn]))639 if (!RTCrX509RelativeDistinguishedName_MatchByRfc5280(pLeft->papItems[iRdn], pRight->papItems[iRdn])) 640 640 return false; 641 641 return true; … … 658 658 for (uint32_t i = 0; pConstraint->cItems; i++) 659 659 { 660 PCRTCRX509RELATIVEDISTINGUISHEDNAME pConstrRdns = &pConstraint->paItems[i];661 PCRTCRX509RELATIVEDISTINGUISHEDNAME pNameRdns = &pName->paItems[i];660 PCRTCRX509RELATIVEDISTINGUISHEDNAME pConstrRdns = pConstraint->papItems[i]; 661 PCRTCRX509RELATIVEDISTINGUISHEDNAME pNameRdns = pName->papItems[i]; 662 662 663 663 /* … … 666 666 for (uint32_t iConstrAttrib = 0; iConstrAttrib < pConstrRdns->cItems; iConstrAttrib++) 667 667 { 668 PCRTCRX509ATTRIBUTETYPEANDVALUE pConstrAttrib = &pConstrRdns->paItems[iConstrAttrib];668 PCRTCRX509ATTRIBUTETYPEANDVALUE pConstrAttrib = pConstrRdns->papItems[iConstrAttrib]; 669 669 670 670 /* … … 673 673 bool fFound = false; 674 674 for (uint32_t iNameAttrib = 0; iNameAttrib < pNameRdns->cItems; iNameAttrib++) 675 if (RTCrX509AttributeTypeAndValue_MatchAsRdnByRfc5280(pConstrAttrib, &pNameRdns->paItems[iNameAttrib]))675 if (RTCrX509AttributeTypeAndValue_MatchAsRdnByRfc5280(pConstrAttrib, pNameRdns->papItems[iNameAttrib])) 676 676 { 677 677 fFound = true; … … 737 737 for (uint32_t i = 0; i < pThis->cItems; i++) 738 738 { 739 PCRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = &pThis->paItems[i];739 PCRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = pThis->papItems[i]; 740 740 for (uint32_t j = 0; j < pRdn->cItems; j++) 741 741 { 742 PCRTCRX509ATTRIBUTETYPEANDVALUE pComponent = &pRdn->paItems[j];742 PCRTCRX509ATTRIBUTETYPEANDVALUE pComponent = pRdn->papItems[j]; 743 743 744 744 /* … … 816 816 for (uint32_t i = 0; i < pThis->cItems; i++) 817 817 { 818 PCRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = &pThis->paItems[i];818 PCRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = pThis->papItems[i]; 819 819 for (uint32_t j = 0; j < pRdn->cItems; j++) 820 820 { 821 PCRTCRX509ATTRIBUTETYPEANDVALUE pComponent = &pRdn->paItems[j];821 PCRTCRX509ATTRIBUTETYPEANDVALUE pComponent = pRdn->papItems[j]; 822 822 823 823 /* … … 1332 1332 { 1333 1333 1334 if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_ANY_EXTENDED_KEY_USAGE_OID) == 0)1334 if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_ANY_EXTENDED_KEY_USAGE_OID) == 0) 1335 1335 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_ANY; 1336 else if (RTAsn1ObjId_StartsWith( &pObjIds->paItems[i], RTCRX509_ID_KP_OID))1337 { 1338 if (RTAsn1ObjIdCountComponents( &pObjIds->paItems[i]) == 9)1339 switch (RTAsn1ObjIdGetLastComponentsAsUInt32( &pObjIds->paItems[i]))1336 else if (RTAsn1ObjId_StartsWith(pObjIds->papItems[i], RTCRX509_ID_KP_OID)) 1337 { 1338 if (RTAsn1ObjIdCountComponents(pObjIds->papItems[i]) == 9) 1339 switch (RTAsn1ObjIdGetLastComponentsAsUInt32(pObjIds->papItems[i])) 1340 1340 { 1341 1341 case 1: pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_SERVER_AUTH; break; … … 1357 1357 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_OTHER; 1358 1358 } 1359 else if (RTAsn1ObjId_StartsWith( &pObjIds->paItems[i], RTCRX509_APPLE_EKU_APPLE_EXTENDED_KEY_USAGE_OID))1360 { 1361 if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_OID) == 0)1359 else if (RTAsn1ObjId_StartsWith(pObjIds->papItems[i], RTCRX509_APPLE_EKU_APPLE_EXTENDED_KEY_USAGE_OID)) 1360 { 1361 if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_OID) == 0) 1362 1362 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_CODE_SIGNING; 1363 else if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_DEVELOPMENT_OID) == 0)1363 else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_DEVELOPMENT_OID) == 0) 1364 1364 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_CODE_SIGNING_DEVELOPMENT; 1365 else if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_APPLE_EKU_SOFTWARE_UPDATE_SIGNING_OID) == 0)1365 else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_SOFTWARE_UPDATE_SIGNING_OID) == 0) 1366 1366 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_SOFTWARE_UPDATE_SIGNING; 1367 else if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_THRID_PARTY_OID) == 0)1367 else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_THRID_PARTY_OID) == 0) 1368 1368 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_CODE_SIGNING_THIRD_PARTY; 1369 else if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_APPLE_EKU_RESOURCE_SIGNING_OID) == 0)1369 else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_RESOURCE_SIGNING_OID) == 0) 1370 1370 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_RESOURCE_SIGNING; 1371 else if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_APPLE_EKU_SYSTEM_IDENTITY_OID) == 0)1371 else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_SYSTEM_IDENTITY_OID) == 0) 1372 1372 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_SYSTEM_IDENTITY; 1373 1373 else 1374 1374 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_OTHER; 1375 1375 } 1376 else if (RTAsn1ObjId_StartsWith( &pObjIds->paItems[i], "1.3.6.1.4.1.311"))1377 { 1378 if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_MS_EKU_TIMESTAMP_SIGNING_OID) == 0)1376 else if (RTAsn1ObjId_StartsWith(pObjIds->papItems[i], "1.3.6.1.4.1.311")) 1377 { 1378 if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_TIMESTAMP_SIGNING_OID) == 0) 1379 1379 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_TIMESTAMP_SIGNING; 1380 else if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_MS_EKU_NT5_CRYPTO_OID) == 0)1380 else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_NT5_CRYPTO_OID) == 0) 1381 1381 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_NT5_CRYPTO; 1382 else if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_MS_EKU_OEM_WHQL_CRYPTO_OID) == 0)1382 else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_OEM_WHQL_CRYPTO_OID) == 0) 1383 1383 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_OEM_WHQL_CRYPTO; 1384 else if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_MS_EKU_EMBEDDED_NT_CRYPTO_OID) == 0)1384 else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_EMBEDDED_NT_CRYPTO_OID) == 0) 1385 1385 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_EMBEDDED_NT_CRYPTO; 1386 else if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_MS_EKU_KERNEL_MODE_CODE_SIGNING_OID) == 0)1386 else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_KERNEL_MODE_CODE_SIGNING_OID) == 0) 1387 1387 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_KERNEL_MODE_CODE_SIGNING; 1388 else if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_MS_EKU_LIFETIME_SIGNING_OID) == 0)1388 else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_LIFETIME_SIGNING_OID) == 0) 1389 1389 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_LIFETIME_SIGNING; 1390 else if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_MS_EKU_DRM_OID) == 0)1390 else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_DRM_OID) == 0) 1391 1391 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_DRM; 1392 else if (RTAsn1ObjId_CompareWithString( &pObjIds->paItems[i], RTCRX509_MS_EKU_DRM_INDIVIDUALIZATION_OID) == 0)1392 else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_DRM_INDIVIDUALIZATION_OID) == 0) 1393 1393 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_DRM_INDIVIDUALIZATION; 1394 1394 else … … 1443 1443 for (uint32_t i = 0; i < pThis->T3.Extensions.cItems; i++) 1444 1444 { 1445 PCRTASN1OBJID pExtnId = &pThis->T3.Extensions.pa Items[i].ExtnId;1446 PCRTASN1OCTETSTRING pExtValue = &pThis->T3.Extensions.pa Items[i].ExtnValue;1445 PCRTASN1OBJID pExtnId = &pThis->T3.Extensions.papItems[i]->ExtnId; 1446 PCRTASN1OCTETSTRING pExtValue = &pThis->T3.Extensions.papItems[i]->ExtnValue; 1447 1447 if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_KEY_USAGE_OID) == 0) 1448 1448 { 1449 1449 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_KEY_USAGE); 1450 rtCrx509TbsCertificate_AddKeyUsageFlags(pThis, &pThis->T3.Extensions.paItems[i]);1451 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_BIT_STRING);1450 rtCrx509TbsCertificate_AddKeyUsageFlags(pThis, pThis->T3.Extensions.papItems[i]); 1451 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_BIT_STRING); 1452 1452 } 1453 1453 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_EXT_KEY_USAGE_OID) == 0) 1454 1454 { 1455 1455 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_EXT_KEY_USAGE); 1456 rtCrx509TbsCertificate_AddExtKeyUsageFlags(pThis, &pThis->T3.Extensions.paItems[i]);1457 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_SEQ_OF_OBJ_IDS);1456 rtCrx509TbsCertificate_AddExtKeyUsageFlags(pThis, pThis->T3.Extensions.papItems[i]); 1457 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_SEQ_OF_OBJ_IDS); 1458 1458 } 1459 1459 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_AUTHORITY_KEY_IDENTIFIER_OID) == 0) … … 1461 1461 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_AUTHORITY_KEY_IDENTIFIER); 1462 1462 pThis->T3.pAuthorityKeyIdentifier = (PCRTCRX509AUTHORITYKEYIDENTIFIER)pExtValue->pEncapsulated; 1463 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_AUTHORITY_KEY_IDENTIFIER);1463 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_AUTHORITY_KEY_IDENTIFIER); 1464 1464 } 1465 1465 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_OLD_AUTHORITY_KEY_IDENTIFIER_OID) == 0) … … 1467 1467 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_OLD_AUTHORITY_KEY_IDENTIFIER); 1468 1468 pThis->T3.pOldAuthorityKeyIdentifier = (PCRTCRX509OLDAUTHORITYKEYIDENTIFIER)pExtValue->pEncapsulated; 1469 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_OLD_AUTHORITY_KEY_IDENTIFIER);1469 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_OLD_AUTHORITY_KEY_IDENTIFIER); 1470 1470 } 1471 1471 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_SUBJECT_KEY_IDENTIFIER_OID) == 0) … … 1473 1473 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_SUBJECT_KEY_IDENTIFIER); 1474 1474 pThis->T3.pSubjectKeyIdentifier = (PCRTASN1OCTETSTRING)pExtValue->pEncapsulated; 1475 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_OCTET_STRING);1475 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_OCTET_STRING); 1476 1476 } 1477 1477 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_SUBJECT_ALT_NAME_OID) == 0) … … 1479 1479 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_SUBJECT_ALT_NAME); 1480 1480 pThis->T3.pAltSubjectName = (PCRTCRX509GENERALNAMES)pExtValue->pEncapsulated; 1481 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES);1481 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES); 1482 1482 } 1483 1483 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_ISSUER_ALT_NAME_OID) == 0) … … 1485 1485 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_ISSUER_ALT_NAME); 1486 1486 pThis->T3.pAltIssuerName = (PCRTCRX509GENERALNAMES)pExtValue->pEncapsulated; 1487 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES);1487 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES); 1488 1488 } 1489 1489 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_CERTIFICATE_POLICIES_OID) == 0) … … 1491 1491 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_CERTIFICATE_POLICIES); 1492 1492 pThis->T3.pCertificatePolicies = (PCRTCRX509CERTIFICATEPOLICIES)pExtValue->pEncapsulated; 1493 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_CERTIFICATE_POLICIES);1493 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_CERTIFICATE_POLICIES); 1494 1494 } 1495 1495 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_POLICY_MAPPINGS_OID) == 0) … … 1497 1497 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_POLICY_MAPPINGS); 1498 1498 pThis->T3.pPolicyMappings = (PCRTCRX509POLICYMAPPINGS)pExtValue->pEncapsulated; 1499 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_POLICY_MAPPINGS);1499 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_POLICY_MAPPINGS); 1500 1500 } 1501 1501 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_BASIC_CONSTRAINTS_OID) == 0) … … 1503 1503 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_BASIC_CONSTRAINTS); 1504 1504 pThis->T3.pBasicConstraints = (PCRTCRX509BASICCONSTRAINTS)pExtValue->pEncapsulated; 1505 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_BASIC_CONSTRAINTS);1505 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_BASIC_CONSTRAINTS); 1506 1506 } 1507 1507 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_NAME_CONSTRAINTS_OID) == 0) … … 1509 1509 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_NAME_CONSTRAINTS); 1510 1510 pThis->T3.pNameConstraints = (PCRTCRX509NAMECONSTRAINTS)pExtValue->pEncapsulated; 1511 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_NAME_CONSTRAINTS);1511 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_NAME_CONSTRAINTS); 1512 1512 } 1513 1513 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_POLICY_CONSTRAINTS_OID) == 0) … … 1515 1515 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_POLICY_CONSTRAINTS); 1516 1516 pThis->T3.pPolicyConstraints = (PCRTCRX509POLICYCONSTRAINTS)pExtValue->pEncapsulated; 1517 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_POLICY_CONSTRAINTS);1517 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_POLICY_CONSTRAINTS); 1518 1518 } 1519 1519 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_INHIBIT_ANY_POLICY_OID) == 0) … … 1521 1521 CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_INHIBIT_ANY_POLICY); 1522 1522 pThis->T3.pInhibitAnyPolicy = (PCRTASN1INTEGER)pExtValue->pEncapsulated; 1523 Assert(pThis->T3.Extensions.pa Items[i].enmValue == RTCRX509EXTENSIONVALUE_INTEGER);1523 Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_INTEGER); 1524 1524 } 1525 1525 else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_ACCEPTABLE_CERT_POLICIES_OID) == 0) … … 1560 1560 for (uint32_t i = 0; i < pThis->TbsCertificate.T3.Extensions.cItems; i++) 1561 1561 { 1562 PCRTCRX509EXTENSION pExt = &pThis->TbsCertificate.T3.Extensions.paItems[i];1562 PCRTCRX509EXTENSION pExt = pThis->TbsCertificate.T3.Extensions.papItems[i]; 1563 1563 if ( pExt->enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES 1564 1564 && RTAsn1ObjId_CompareWithString(&pExt->ExtnId, RTCRX509_ID_CE_SUBJECT_ALT_NAME_OID)) … … 1566 1566 PCRTCRX509GENERALNAMES pGeneralNames = (PCRTCRX509GENERALNAMES)pExt->ExtnValue.pEncapsulated; 1567 1567 for (uint32_t j = 0; j < pGeneralNames->cItems; j++) 1568 if ( RTCRX509GENERALNAME_IS_DIRECTORY_NAME( &pGeneralNames->paItems[j])1569 && RTCrX509Name_MatchByRfc5280(&pGeneralNames->pa Items[j].u.pT4->DirectoryName, pName))1568 if ( RTCRX509GENERALNAME_IS_DIRECTORY_NAME(pGeneralNames->papItems[j]) 1569 && RTCrX509Name_MatchByRfc5280(&pGeneralNames->papItems[j]->u.pT4->DirectoryName, pName)) 1570 1570 return true; 1571 1571 } … … 1595 1595 { 1596 1596 for (uint32_t i = 0; i < pCertificates->cItems; i++) 1597 if (RTCrX509Certificate_MatchIssuerAndSerialNumber( &pCertificates->paItems[i], pIssuer, pSerialNumber))1598 return &pCertificates->paItems[i];1597 if (RTCrX509Certificate_MatchIssuerAndSerialNumber(pCertificates->papItems[i], pIssuer, pSerialNumber)) 1598 return pCertificates->papItems[i]; 1599 1599 return NULL; 1600 1600 } -
trunk/src/VBox/Runtime/common/crypto/x509-init.cpp
r62477 r64883 49 49 { 50 50 uint32_t cRdns = pThis->cItems; 51 PRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = &pThis->paItems[0];51 PRTCRX509RELATIVEDISTINGUISHEDNAME *ppRdn = pThis->papItems; 52 52 while (cRdns-- > 0) 53 53 { 54 uint32_t cAttribs = pRdn->cItems; 55 PRTCRX509ATTRIBUTETYPEANDVALUE pAttrib = &pRdn->paItems[0]; 54 PRTCRX509RELATIVEDISTINGUISHEDNAME const pRdn = *ppRdn; 55 uint32_t cAttribs = pRdn->cItems; 56 PRTCRX509ATTRIBUTETYPEANDVALUE *ppAttrib = pRdn->papItems; 56 57 while (cAttribs-- > 0) 57 58 { 59 PRTCRX509ATTRIBUTETYPEANDVALUE const pAttrib = *ppAttrib; 58 60 if (pAttrib->Value.enmType == RTASN1TYPE_STRING) 59 61 { … … 62 64 return rc; 63 65 } 64 p Attrib++;66 ppAttrib++; 65 67 } 66 p Rdn++;68 ppRdn++; 67 69 } 68 70 return VINF_SUCCESS; -
trunk/src/VBox/Runtime/common/crypto/x509-sanity.cpp
r62564 r64883 59 59 for (uint32_t i = 0; i < pThis->cItems; i++) 60 60 { 61 if (pThis->cItems == 0) 61 PCRTCRX509RELATIVEDISTINGUISHEDNAME const pRdn = pThis->papItems[i]; 62 if (pRdn->cItems == 0) 62 63 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_EMPTY_SUB_SET, 63 64 "%s: Items[%u] has no sub components.", pszErrorTag, i); 64 65 65 for (uint32_t j = 0; j < p This->paItems[i].cItems; j++)66 for (uint32_t j = 0; j < pRdn->cItems; j++) 66 67 { 67 if (pThis->paItems[i].paItems[j].Value.enmType != RTASN1TYPE_STRING) 68 PCRTCRX509ATTRIBUTETYPEANDVALUE const pAttr = pRdn->papItems[j]; 69 70 if (pAttr->Value.enmType != RTASN1TYPE_STRING) 68 71 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_NOT_STRING, 69 72 "%s: Items[%u].paItems[%u].enmType is %d instead of string (%d).", 70 pszErrorTag, i, j, p This->paItems[i].paItems[j].Value.enmType, RTASN1TYPE_STRING);71 if (p This->paItems[i].paItems[j].Value.u.String.Asn1Core.cb == 0)73 pszErrorTag, i, j, pAttr->Value.enmType, RTASN1TYPE_STRING); 74 if (pAttr->Value.u.String.Asn1Core.cb == 0) 72 75 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_EMPTY_STRING, 73 76 "%s: Items[%u].paItems[%u] is an empty string", pszErrorTag, i, j); 74 switch (p This->paItems[i].paItems[j].Value.u.String.Asn1Core.uTag)77 switch (pAttr->Value.u.String.Asn1Core.uTag) 75 78 { 76 79 case ASN1_TAG_PRINTABLE_STRING: … … 86 89 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_INVALID_NAME_STRING_TAG, 87 90 "%s: Items[%u].paItems[%u] invalid string type: %u", pszErrorTag, i, j, 88 p This->paItems[i].paItems[j].Value.u.String.Asn1Core.uTag);91 pAttr->Value.u.String.Asn1Core.uTag); 89 92 } 90 93 } -
trunk/src/VBox/Runtime/tools/RTSignTool.cpp
r64877 r64883 63 63 64 64 65 typedef struct SHOWEXEPKCS7 66 { 67 uint8_t const *pbBuf; 65 /** 66 * PKCS\#7 signature data. 67 */ 68 typedef struct SIGNTOOLPKCS7 69 { 70 /** The raw signature. */ 71 uint8_t *pbBuf; 72 /** Size of the raw signature. */ 68 73 size_t cbBuf; 74 /** The filename. */ 69 75 const char *pszFilename; 70 unsigned cVerbosity;71 RTLDRMOD hLdrMod;72 76 /** The outer content info wrapper. */ 73 77 RTCRPKCS7CONTENTINFO ContentInfo; … … 76 80 /** Pointer to the indirect data content. */ 77 81 PRTCRSPCINDIRECTDATACONTENT pIndData; 78 82 } SIGNTOOLPKCS7; 83 typedef SIGNTOOLPKCS7 *PSIGNTOOLPKCS7; 84 85 86 /** 87 * PKCS\#7 signature data for executable. 88 */ 89 typedef struct SIGNTOOLPKCS7EXE : public SIGNTOOLPKCS7 90 { 91 /** The module handle. */ 92 RTLDRMOD hLdrMod; 93 } SIGNTOOLPKCS7EXE; 94 typedef SIGNTOOLPKCS7EXE *PSIGNTOOLPKCS7EXE; 95 96 97 /** 98 * Data for the show exe (signature) command. 99 */ 100 typedef struct SHOWEXEPKCS7 : public SIGNTOOLPKCS7EXE 101 { 102 /** The verbosity. */ 103 unsigned cVerbosity; 104 /** The prefix buffer. */ 79 105 char szPrefix[256]; 106 /** Temporary buffer. */ 80 107 char szTmp[4096]; 81 108 } SHOWEXEPKCS7; … … 94 121 95 122 96 97 98 /*99 * The 'extract-exe-signer-cert' command.100 */101 static RTEXITCODE HelpExtractExeSignerCert(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)102 {103 RT_NOREF_PV(enmLevel);104 RTStrmPrintf(pStrm, "extract-exe-signer-cert [--ber|--cer|--der] [--exe|-e] <exe> [--output|-o] <outfile.cer>\n");105 return RTEXITCODE_SUCCESS;106 }107 108 static RTEXITCODE HandleExtractExeSignerCert(int cArgs, char **papszArgs)109 {110 /*111 * Parse arguments.112 */113 static const RTGETOPTDEF s_aOptions[] =114 {115 { "--ber", 'b', RTGETOPT_REQ_NOTHING },116 { "--cer", 'c', RTGETOPT_REQ_NOTHING },117 { "--der", 'd', RTGETOPT_REQ_NOTHING },118 { "--exe", 'e', RTGETOPT_REQ_STRING },119 { "--output", 'o', RTGETOPT_REQ_STRING },120 };121 122 const char *pszExe = NULL;123 const char *pszOut = NULL;124 RTLDRARCH enmLdrArch = RTLDRARCH_WHATEVER;125 uint32_t fCursorFlags = RTASN1CURSOR_FLAGS_DER;126 127 RTGETOPTSTATE GetState;128 int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);129 AssertRCReturn(rc, RTEXITCODE_FAILURE);130 RTGETOPTUNION ValueUnion;131 int ch;132 while ((ch = RTGetOpt(&GetState, &ValueUnion)))133 {134 switch (ch)135 {136 case 'e': pszExe = ValueUnion.psz; break;137 case 'o': pszOut = ValueUnion.psz; break;138 case 'b': fCursorFlags = 0; break;139 case 'c': fCursorFlags = RTASN1CURSOR_FLAGS_CER; break;140 case 'd': fCursorFlags = RTASN1CURSOR_FLAGS_DER; break;141 case 'V': return HandleVersion(cArgs, papszArgs);142 case 'h': return HelpExtractExeSignerCert(g_pStdOut, RTSIGNTOOLHELP_FULL);143 144 case VINF_GETOPT_NOT_OPTION:145 if (!pszExe)146 pszExe = ValueUnion.psz;147 else if (!pszOut)148 pszOut = ValueUnion.psz;149 else150 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many file arguments: %s", ValueUnion.psz);151 break;152 153 default:154 return RTGetOptPrintError(ch, &ValueUnion);155 }156 }157 if (!pszExe)158 return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given.");159 if (!pszOut)160 return RTMsgErrorExit(RTEXITCODE_FAILURE, "No output file given.");161 if (RTPathExists(pszOut))162 return RTMsgErrorExit(RTEXITCODE_FAILURE, "The output file '%s' exists.", pszOut);163 164 /*165 * Do it.166 */167 168 /* Open the executable image and query the PKCS7 info. */169 RTLDRMOD hLdrMod;170 rc = RTLdrOpen(pszExe, RTLDR_O_FOR_VALIDATION, enmLdrArch, &hLdrMod);171 if (RT_FAILURE(rc))172 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszExe, rc);173 174 RTEXITCODE rcExit = RTEXITCODE_FAILURE;175 #ifdef DEBUG176 size_t cbBuf = 64;177 #else178 size_t cbBuf = _512K;179 #endif180 void *pvBuf = RTMemAlloc(cbBuf);181 size_t cbRet = 0;182 rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbRet);183 if (rc == VERR_BUFFER_OVERFLOW && cbRet < _4M && cbRet > 0)184 {185 RTMemFree(pvBuf);186 cbBuf = cbRet;187 pvBuf = RTMemAlloc(cbBuf);188 rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbRet);189 }190 if (RT_SUCCESS(rc))191 {192 static RTERRINFOSTATIC s_StaticErrInfo;193 RTErrInfoInitStatic(&s_StaticErrInfo);194 195 /*196 * Decode the output.197 */198 RTASN1CURSORPRIMARY PrimaryCursor;199 RTAsn1CursorInitPrimary(&PrimaryCursor, pvBuf, (uint32_t)cbRet, &s_StaticErrInfo.Core,200 &g_RTAsn1DefaultAllocator, fCursorFlags, "exe");201 RTCRPKCS7CONTENTINFO Pkcs7Ci;202 rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &Pkcs7Ci, "pkcs7");203 if (RT_SUCCESS(rc))204 {205 if (RTCrPkcs7ContentInfo_IsSignedData(&Pkcs7Ci))206 {207 PCRTCRPKCS7SIGNEDDATA pSd = Pkcs7Ci.u.pSignedData;208 if (pSd->SignerInfos.cItems == 1)209 {210 PCRTCRPKCS7ISSUERANDSERIALNUMBER pISN = &pSd->SignerInfos.paItems[0].IssuerAndSerialNumber;211 PCRTCRX509CERTIFICATE pCert;212 pCert = RTCrPkcs7SetOfCerts_FindX509ByIssuerAndSerialNumber(&pSd->Certificates,213 &pISN->Name, &pISN->SerialNumber);214 if (pCert)215 {216 /*217 * Write it out.218 */219 RTFILE hFile;220 rc = RTFileOpen(&hFile, pszOut, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE);221 if (RT_SUCCESS(rc))222 {223 uint32_t cbCert = pCert->SeqCore.Asn1Core.cbHdr + pCert->SeqCore.Asn1Core.cb;224 rc = RTFileWrite(hFile, pCert->SeqCore.Asn1Core.uData.pu8 - pCert->SeqCore.Asn1Core.cbHdr,225 cbCert, NULL);226 if (RT_SUCCESS(rc))227 {228 rc = RTFileClose(hFile);229 if (RT_SUCCESS(rc))230 {231 hFile = NIL_RTFILE;232 rcExit = RTEXITCODE_SUCCESS;233 RTMsgInfo("Successfully wrote %u bytes to '%s'", cbCert, pszOut);234 }235 else236 RTMsgError("RTFileClose failed: %Rrc", rc);237 }238 else239 RTMsgError("RTFileWrite failed: %Rrc", rc);240 RTFileClose(hFile);241 }242 else243 RTMsgError("Error opening '%s': %Rrc", pszOut, rc);244 }245 else246 RTMsgError("Certificate not found.");247 }248 else249 RTMsgError("SignerInfo count: %u", pSd->SignerInfos.cItems);250 }251 else252 RTMsgError("No PKCS7 content: ContentType=%s", Pkcs7Ci.ContentType.szObjId);253 RTAsn1VtDelete(&Pkcs7Ci.SeqCore.Asn1Core);254 }255 else256 RTMsgError("RTPkcs7ContentInfoDecodeAsn1 failed: %Rrc - %s", rc, s_StaticErrInfo.szMsg);257 }258 else259 RTMsgError("RTLDRPROP_PKCS7_SIGNED_DATA failed on '%s': %Rrc", pszExe, rc);260 RTMemFree(pvBuf);261 rc = RTLdrClose(hLdrMod);262 if (RT_FAILURE(rc))263 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc);264 return rcExit;265 }266 267 #ifndef IPRT_IN_BUILD_TOOL268 269 /*270 * The 'verify-exe' command.271 */272 static RTEXITCODE HelpVerifyExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)273 {274 RT_NOREF_PV(enmLevel);275 RTStrmPrintf(pStrm,276 "verify-exe [--verbose|--quiet] [--kernel] [--root <root-cert.der>] [--additional <supp-cert.der>]\n"277 " [--type <win|osx>] <exe1> [exe2 [..]]\n");278 return RTEXITCODE_SUCCESS;279 }280 281 typedef struct VERIFYEXESTATE282 {283 RTCRSTORE hRootStore;284 RTCRSTORE hKernelRootStore;285 RTCRSTORE hAdditionalStore;286 bool fKernel;287 int cVerbose;288 enum { kSignType_Windows, kSignType_OSX } enmSignType;289 uint64_t uTimestamp;290 RTLDRARCH enmLdrArch;291 } VERIFYEXESTATE;292 293 # ifdef VBOX294 /** Certificate store load set.295 * Declared outside HandleVerifyExe because of braindead gcc visibility crap. */296 struct STSTORESET297 {298 RTCRSTORE hStore;299 PCSUPTAENTRY paTAs;300 unsigned cTAs;301 };302 # endif303 304 123 /** 305 * @callback_method_impl{FNRTCRPKCS7VERIFYCERTCALLBACK, 306 * Standard code signing. Use this for Microsoft SPC.} 307 */ 308 static DECLCALLBACK(int) VerifyExecCertVerifyCallback(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags, 309 void *pvUser, PRTERRINFO pErrInfo) 310 { 311 VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser; 312 uint32_t cPaths = hCertPaths != NIL_RTCRX509CERTPATHS ? RTCrX509CertPathsGetPathCount(hCertPaths) : 0; 313 314 /* 315 * Dump all the paths. 316 */ 317 if (pState->cVerbose > 0) 318 { 319 for (uint32_t iPath = 0; iPath < cPaths; iPath++) 320 { 321 RTPrintf("---\n"); 322 RTCrX509CertPathsDumpOne(hCertPaths, iPath, pState->cVerbose, RTStrmDumpPrintfV, g_pStdOut); 323 *pErrInfo->pszMsg = '\0'; 324 } 325 RTPrintf("---\n"); 326 } 327 328 /* 329 * Test signing certificates normally doesn't have all the necessary 330 * features required below. So, treat them as special cases. 331 */ 332 if ( hCertPaths == NIL_RTCRX509CERTPATHS 333 && RTCrX509Name_Compare(&pCert->TbsCertificate.Issuer, &pCert->TbsCertificate.Subject) == 0) 334 { 335 RTMsgInfo("Test signed.\n"); 336 return VINF_SUCCESS; 337 } 338 339 if (hCertPaths == NIL_RTCRX509CERTPATHS) 340 RTMsgInfo("Signed by trusted certificate.\n"); 341 342 /* 343 * Standard code signing capabilites required. 344 */ 345 int rc = RTCrPkcs7VerifyCertCallbackCodeSigning(pCert, hCertPaths, fFlags, NULL, pErrInfo); 346 if ( RT_SUCCESS(rc) 347 && (fFlags & RTCRPKCS7VCC_F_SIGNED_DATA)) 348 { 349 /* 350 * If kernel signing, a valid certificate path must be anchored by the 351 * microsoft kernel signing root certificate. The only alternative is 352 * test signing. 353 */ 354 if (pState->fKernel && hCertPaths != NIL_RTCRX509CERTPATHS) 355 { 356 uint32_t cFound = 0; 357 uint32_t cValid = 0; 358 for (uint32_t iPath = 0; iPath < cPaths; iPath++) 359 { 360 bool fTrusted; 361 PCRTCRX509NAME pSubject; 362 PCRTCRX509SUBJECTPUBLICKEYINFO pPublicKeyInfo; 363 int rcVerify; 364 rc = RTCrX509CertPathsQueryPathInfo(hCertPaths, iPath, &fTrusted, NULL /*pcNodes*/, &pSubject, &pPublicKeyInfo, 365 NULL, NULL /*pCertCtx*/, &rcVerify); 366 AssertRCBreak(rc); 367 368 if (RT_SUCCESS(rcVerify)) 369 { 370 Assert(fTrusted); 371 cValid++; 372 373 /* Search the kernel signing root store for a matching anchor. */ 374 RTCRSTORECERTSEARCH Search; 375 rc = RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280(pState->hKernelRootStore, pSubject, &Search); 376 AssertRCBreak(rc); 377 PCRTCRCERTCTX pCertCtx; 378 while ((pCertCtx = RTCrStoreCertSearchNext(pState->hKernelRootStore, &Search)) != NULL) 379 { 380 PCRTCRX509SUBJECTPUBLICKEYINFO pPubKeyInfo; 381 if (pCertCtx->pCert) 382 pPubKeyInfo = &pCertCtx->pCert->TbsCertificate.SubjectPublicKeyInfo; 383 else if (pCertCtx->pTaInfo) 384 pPubKeyInfo = &pCertCtx->pTaInfo->PubKey; 385 else 386 pPubKeyInfo = NULL; 387 if (RTCrX509SubjectPublicKeyInfo_Compare(pPubKeyInfo, pPublicKeyInfo) == 0) 388 cFound++; 389 RTCrCertCtxRelease(pCertCtx); 390 } 391 392 int rc2 = RTCrStoreCertSearchDestroy(pState->hKernelRootStore, &Search); AssertRC(rc2); 393 } 394 } 395 if (RT_SUCCESS(rc) && cFound == 0) 396 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "Not valid kernel code signature."); 397 if (RT_SUCCESS(rc) && cValid != 2) 398 RTMsgWarning("%u valid paths, expected 2", cValid); 399 } 400 } 401 402 return rc; 403 } 404 405 406 /** @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA} */ 407 static DECLCALLBACK(int) VerifyExeCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature, 408 void const *pvSignature, size_t cbSignature, 409 PRTERRINFO pErrInfo, void *pvUser) 410 { 411 VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser; 412 RT_NOREF_PV(hLdrMod); RT_NOREF_PV(cbSignature); 413 414 switch (enmSignature) 415 { 416 case RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA: 417 { 418 PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature; 419 420 RTTIMESPEC ValidationTime; 421 RTTimeSpecSetSeconds(&ValidationTime, pState->uTimestamp); 422 423 /* 424 * Dump the signed data if so requested. 425 */ 426 if (pState->cVerbose) 427 RTAsn1Dump(&pContentInfo->SeqCore.Asn1Core, 0, 0, RTStrmDumpPrintfV, g_pStdOut); 428 429 430 /* 431 * Do the actual verification. Will have to modify this so it takes 432 * the authenticode policies into account. 433 */ 434 return RTCrPkcs7VerifySignedData(pContentInfo, 435 RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY 436 | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT 437 | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT, 438 pState->hAdditionalStore, pState->hRootStore, &ValidationTime, 439 VerifyExecCertVerifyCallback, pState, pErrInfo); 440 } 441 442 default: 443 return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", enmSignature); 444 } 445 } 446 447 /** Worker for HandleVerifyExe. */ 448 static RTEXITCODE HandleVerifyExeWorker(VERIFYEXESTATE *pState, const char *pszFilename, PRTERRINFOSTATIC pStaticErrInfo) 449 { 450 /* 451 * Open the executable image and verify it. 452 */ 453 RTLDRMOD hLdrMod; 454 int rc = RTLdrOpen(pszFilename, RTLDR_O_FOR_VALIDATION, pState->enmLdrArch, &hLdrMod); 455 if (RT_FAILURE(rc)) 456 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszFilename, rc); 457 458 459 rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &pState->uTimestamp, sizeof(pState->uTimestamp)); 460 if (RT_SUCCESS(rc)) 461 { 462 rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo)); 463 if (RT_SUCCESS(rc)) 464 RTMsgInfo("'%s' is valid.\n", pszFilename); 465 else if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME) 466 { 467 RTTIMESPEC Now; 468 pState->uTimestamp = RTTimeSpecGetSeconds(RTTimeNow(&Now)); 469 rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo)); 470 if (RT_SUCCESS(rc)) 471 RTMsgInfo("'%s' is valid now, but not at link time.\n", pszFilename); 472 } 473 if (RT_FAILURE(rc)) 474 RTMsgError("RTLdrVerifySignature failed on '%s': %Rrc - %s\n", pszFilename, rc, pStaticErrInfo->szMsg); 475 } 476 else 477 RTMsgError("RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on '%s': %Rrc\n", pszFilename, rc); 478 479 int rc2 = RTLdrClose(hLdrMod); 480 if (RT_FAILURE(rc2)) 481 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc2); 482 if (RT_FAILURE(rc)) 483 return rc != VERR_LDRVI_NOT_SIGNED ? RTEXITCODE_FAILURE : RTEXITCODE_SKIPPED; 484 485 return RTEXITCODE_SUCCESS; 486 } 487 488 489 static RTEXITCODE HandleVerifyExe(int cArgs, char **papszArgs) 490 { 491 RTERRINFOSTATIC StaticErrInfo; 492 493 /* Note! This code does not try to clean up the crypto stores on failure. 494 This is intentional as the code is only expected to be used in a 495 one-command-per-process environment where we do exit() upon 496 returning from this function. */ 497 498 /* 499 * Parse arguments. 500 */ 501 static const RTGETOPTDEF s_aOptions[] = 502 { 503 { "--kernel", 'k', RTGETOPT_REQ_NOTHING }, 504 { "--root", 'r', RTGETOPT_REQ_STRING }, 505 { "--additional", 'a', RTGETOPT_REQ_STRING }, 506 { "--add", 'a', RTGETOPT_REQ_STRING }, 507 { "--type", 't', RTGETOPT_REQ_STRING }, 508 { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, 509 { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, 510 }; 511 512 VERIFYEXESTATE State = 513 { 514 NIL_RTCRSTORE, NIL_RTCRSTORE, NIL_RTCRSTORE, false, false, 515 VERIFYEXESTATE::kSignType_Windows, 0, RTLDRARCH_WHATEVER 516 }; 517 int rc = RTCrStoreCreateInMem(&State.hRootStore, 0); 518 if (RT_SUCCESS(rc)) 519 rc = RTCrStoreCreateInMem(&State.hKernelRootStore, 0); 520 if (RT_SUCCESS(rc)) 521 rc = RTCrStoreCreateInMem(&State.hAdditionalStore, 0); 522 if (RT_FAILURE(rc)) 523 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error creating in-memory certificate store: %Rrc", rc); 524 525 RTGETOPTSTATE GetState; 526 rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); 527 AssertRCReturn(rc, RTEXITCODE_FAILURE); 528 RTGETOPTUNION ValueUnion; 529 int ch; 530 while ((ch = RTGetOpt(&GetState, &ValueUnion)) && ch != VINF_GETOPT_NOT_OPTION) 531 { 532 switch (ch) 533 { 534 case 'r': case 'a': 535 rc = RTCrStoreCertAddFromFile(ch == 'r' ? State.hRootStore : State.hAdditionalStore, 536 RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR, 537 ValueUnion.psz, RTErrInfoInitStatic(&StaticErrInfo)); 538 if (RT_FAILURE(rc)) 539 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error loading certificate '%s': %Rrc - %s", 540 ValueUnion.psz, rc, StaticErrInfo.szMsg); 541 if (RTErrInfoIsSet(&StaticErrInfo.Core)) 542 RTMsgWarning("Warnings loading certificate '%s': %s", ValueUnion.psz, StaticErrInfo.szMsg); 543 break; 544 545 case 't': 546 if (!strcmp(ValueUnion.psz, "win") || !strcmp(ValueUnion.psz, "windows")) 547 State.enmSignType = VERIFYEXESTATE::kSignType_Windows; 548 else if (!strcmp(ValueUnion.psz, "osx") || !strcmp(ValueUnion.psz, "apple")) 549 State.enmSignType = VERIFYEXESTATE::kSignType_OSX; 550 else 551 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown signing type: '%s'", ValueUnion.psz); 552 break; 553 554 case 'k': State.fKernel = true; break; 555 case 'v': State.cVerbose++; break; 556 case 'q': State.cVerbose = 0; break; 557 case 'V': return HandleVersion(cArgs, papszArgs); 558 case 'h': return HelpVerifyExe(g_pStdOut, RTSIGNTOOLHELP_FULL); 559 default: return RTGetOptPrintError(ch, &ValueUnion); 560 } 561 } 562 if (ch != VINF_GETOPT_NOT_OPTION) 563 return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given."); 564 565 /* 566 * Populate the certificate stores according to the signing type. 567 */ 568 #ifdef VBOX 569 unsigned cSets = 0; 570 struct STSTORESET aSets[6]; 571 #endif 572 573 switch (State.enmSignType) 574 { 575 case VERIFYEXESTATE::kSignType_Windows: 576 #ifdef VBOX 577 aSets[cSets].hStore = State.hRootStore; 578 aSets[cSets].paTAs = g_aSUPTimestampTAs; 579 aSets[cSets].cTAs = g_cSUPTimestampTAs; 580 cSets++; 581 aSets[cSets].hStore = State.hRootStore; 582 aSets[cSets].paTAs = g_aSUPSpcRootTAs; 583 aSets[cSets].cTAs = g_cSUPSpcRootTAs; 584 cSets++; 585 aSets[cSets].hStore = State.hRootStore; 586 aSets[cSets].paTAs = g_aSUPNtKernelRootTAs; 587 aSets[cSets].cTAs = g_cSUPNtKernelRootTAs; 588 cSets++; 589 aSets[cSets].hStore = State.hKernelRootStore; 590 aSets[cSets].paTAs = g_aSUPNtKernelRootTAs; 591 aSets[cSets].cTAs = g_cSUPNtKernelRootTAs; 592 cSets++; 593 #endif 594 break; 595 596 case VERIFYEXESTATE::kSignType_OSX: 597 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Mac OS X executable signing is not implemented."); 598 } 599 600 #ifdef VBOX 601 for (unsigned i = 0; i < cSets; i++) 602 for (unsigned j = 0; j < aSets[i].cTAs; j++) 603 { 604 rc = RTCrStoreCertAddEncoded(aSets[i].hStore, RTCRCERTCTX_F_ENC_TAF_DER, aSets[i].paTAs[j].pch, 605 aSets[i].paTAs[j].cb, RTErrInfoInitStatic(&StaticErrInfo)); 606 if (RT_FAILURE(rc)) 607 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTCrStoreCertAddEncoded failed (%u/%u): %s", 608 i, j, StaticErrInfo.szMsg); 609 } 610 #endif 611 612 /* 613 * Do it. 614 */ 615 RTEXITCODE rcExit; 616 for (;;) 617 { 618 rcExit = HandleVerifyExeWorker(&State, ValueUnion.psz, &StaticErrInfo); 619 if (rcExit != RTEXITCODE_SUCCESS) 620 break; 621 622 /* 623 * Next file 624 */ 625 ch = RTGetOpt(&GetState, &ValueUnion); 626 if (ch == 0) 627 break; 628 if (ch != VINF_GETOPT_NOT_OPTION) 629 { 630 rcExit = RTGetOptPrintError(ch, &ValueUnion); 631 break; 632 } 633 } 634 635 /* 636 * Clean up. 637 */ 638 uint32_t cRefs; 639 cRefs = RTCrStoreRelease(State.hRootStore); Assert(cRefs == 0); 640 cRefs = RTCrStoreRelease(State.hKernelRootStore); Assert(cRefs == 0); 641 cRefs = RTCrStoreRelease(State.hAdditionalStore); Assert(cRefs == 0); 642 643 return rcExit; 644 } 645 646 #endif /* !IPRT_IN_BUILD_TOOL */ 647 //// 648 #ifndef IPRT_IN_BUILD_TOOL 649 650 /* 651 * The 'show-exe' command. 652 */ 653 static RTEXITCODE HelpShowExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel) 654 { 655 RT_NOREF_PV(enmLevel); 656 RTStrmPrintf(pStrm, 657 "show-exe [--verbose|-v] [--quiet|-q] <exe1> [exe2 [..]]\n"); 658 return RTEXITCODE_SUCCESS; 124 * Deletes the structure. 125 * 126 * @param pThis The structure to initialize. 127 */ 128 static void SignToolPkcs7_Delete(PSIGNTOOLPKCS7 pThis) 129 { 130 RTCrPkcs7ContentInfo_Delete(&pThis->ContentInfo); 131 pThis->pIndData = NULL; 132 pThis->pSignedData = NULL; 133 pThis->pIndData = NULL; 134 RTMemFree(pThis->pbBuf); 135 pThis->pbBuf = NULL; 136 pThis->cbBuf = 0; 137 } 138 139 140 /** 141 * Deletes the structure. 142 * 143 * @param pThis The structure to initialize. 144 */ 145 static void SignToolPkcs7Exe_Delete(PSIGNTOOLPKCS7EXE pThis) 146 { 147 if (pThis->hLdrMod != NIL_RTLDRMOD) 148 { 149 int rc2 = RTLdrClose(pThis->hLdrMod); 150 if (RT_FAILURE(rc2)) 151 RTMsgError("RTLdrClose failed: %Rrc\n", rc2); 152 pThis->hLdrMod = NIL_RTLDRMOD; 153 } 154 SignToolPkcs7_Delete(pThis); 659 155 } 660 156 … … 663 159 * Decodes the PKCS #7 blob pointed to by pThis->pbBuf. 664 160 * 665 * @returns IPRT status code .666 * @param pThis The show exe instance data.667 */ 668 static int HandleShowExeWorkerPkcs7Decode(PSHOWEXEPKCS7 pThis)161 * @returns IPRT status code (error message already shown on failure). 162 * @param pThis The PKCS\#7 signature to decode. 163 */ 164 static int SignToolPkcs7_Decode(PSIGNTOOLPKCS7 pThis) 669 165 { 670 166 RTERRINFOSTATIC ErrInfo; … … 724 220 725 221 /** 222 * Reads and decodes PKCS\#7 signature from the given executable. 223 * 224 * @returns RTEXITCODE_SUCCESS on success, RTEXITCODE_FAILURE with error message 225 * on failure. 226 * @param pThis The structure to initialize. 227 * @param pszFilename The executable filename. 228 * @param cVerbosity The verbosity. 229 * @param enmLdrArch For FAT binaries. 230 */ 231 static RTEXITCODE SignToolPkcs7Exe_InitFromFile(PSIGNTOOLPKCS7EXE pThis, const char *pszFilename, 232 unsigned cVerbosity, RTLDRARCH enmLdrArch = RTLDRARCH_WHATEVER) 233 { 234 /* 235 * Init the return structure. 236 */ 237 RT_ZERO(*pThis); 238 pThis->hLdrMod = NIL_RTLDRMOD; 239 pThis->pszFilename = pszFilename; 240 241 /* 242 * Open the image and check if it's signed. 243 */ 244 int rc = RTLdrOpen(pszFilename, RTLDR_O_FOR_VALIDATION, enmLdrArch, &pThis->hLdrMod); 245 if (RT_SUCCESS(rc)) 246 { 247 bool fIsSigned = false; 248 rc = RTLdrQueryProp(pThis->hLdrMod, RTLDRPROP_IS_SIGNED, &fIsSigned, sizeof(fIsSigned)); 249 if (RT_SUCCESS(rc) && fIsSigned) 250 { 251 /* 252 * Query the PKCS#7 data (assuming M$ style signing) and hand it to a worker. 253 */ 254 size_t cbActual = 0; 255 #ifdef DEBUG 256 size_t cbBuf = 64; 257 #else 258 size_t cbBuf = _512K; 259 #endif 260 void *pvBuf = RTMemAllocZ(cbBuf); 261 if (pvBuf) 262 { 263 rc = RTLdrQueryPropEx(pThis->hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbActual); 264 if (rc == VERR_BUFFER_OVERFLOW) 265 { 266 RTMemFree(pvBuf); 267 cbBuf = cbActual; 268 pvBuf = RTMemAllocZ(cbActual); 269 if (pvBuf) 270 rc = RTLdrQueryPropEx(pThis->hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, 271 pvBuf, cbBuf, &cbActual); 272 else 273 rc = VERR_NO_MEMORY; 274 } 275 } 276 else 277 rc = VERR_NO_MEMORY; 278 279 pThis->pbBuf = (uint8_t *)pvBuf; 280 pThis->cbBuf = cbActual; 281 if (RT_SUCCESS(rc)) 282 { 283 if (cVerbosity > 2) 284 RTPrintf("PKCS#7 signature: %u bytes\n", cbActual); 285 286 /* 287 * Decode it. 288 */ 289 rc = SignToolPkcs7_Decode(pThis); 290 if (RT_SUCCESS(rc)) 291 return RTEXITCODE_SUCCESS; 292 } 293 else 294 RTMsgError("RTLdrQueryPropEx/RTLDRPROP_PKCS7_SIGNED_DATA failed on '%s': %Rrc\n", pszFilename, rc); 295 } 296 else if (RT_SUCCESS(rc)) 297 RTMsgInfo("'%s': not signed\n", pszFilename); 298 else 299 RTMsgError("RTLdrQueryProp/RTLDRPROP_IS_SIGNED failed on '%s': %Rrc\n", pszFilename, rc); 300 } 301 else 302 RTMsgError("Error opening executable image '%s': %Rrc", pszFilename, rc); 303 304 SignToolPkcs7Exe_Delete(pThis); 305 return RTEXITCODE_FAILURE; 306 307 } 308 309 310 /* 311 * The 'extract-exe-signer-cert' command. 312 */ 313 static RTEXITCODE HelpExtractExeSignerCert(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel) 314 { 315 RT_NOREF_PV(enmLevel); 316 RTStrmPrintf(pStrm, "extract-exe-signer-cert [--ber|--cer|--der] [--exe|-e] <exe> [--output|-o] <outfile.cer>\n"); 317 return RTEXITCODE_SUCCESS; 318 } 319 320 static RTEXITCODE HandleExtractExeSignerCert(int cArgs, char **papszArgs) 321 { 322 /* 323 * Parse arguments. 324 */ 325 static const RTGETOPTDEF s_aOptions[] = 326 { 327 { "--ber", 'b', RTGETOPT_REQ_NOTHING }, 328 { "--cer", 'c', RTGETOPT_REQ_NOTHING }, 329 { "--der", 'd', RTGETOPT_REQ_NOTHING }, 330 { "--exe", 'e', RTGETOPT_REQ_STRING }, 331 { "--output", 'o', RTGETOPT_REQ_STRING }, 332 }; 333 334 const char *pszExe = NULL; 335 const char *pszOut = NULL; 336 RTLDRARCH enmLdrArch = RTLDRARCH_WHATEVER; 337 unsigned cVerbosity = 0; 338 uint32_t fCursorFlags = RTASN1CURSOR_FLAGS_DER; 339 340 RTGETOPTSTATE GetState; 341 int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); 342 AssertRCReturn(rc, RTEXITCODE_FAILURE); 343 RTGETOPTUNION ValueUnion; 344 int ch; 345 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 346 { 347 switch (ch) 348 { 349 case 'e': pszExe = ValueUnion.psz; break; 350 case 'o': pszOut = ValueUnion.psz; break; 351 case 'b': fCursorFlags = 0; break; 352 case 'c': fCursorFlags = RTASN1CURSOR_FLAGS_CER; break; 353 case 'd': fCursorFlags = RTASN1CURSOR_FLAGS_DER; break; 354 case 'V': return HandleVersion(cArgs, papszArgs); 355 case 'h': return HelpExtractExeSignerCert(g_pStdOut, RTSIGNTOOLHELP_FULL); 356 357 case VINF_GETOPT_NOT_OPTION: 358 if (!pszExe) 359 pszExe = ValueUnion.psz; 360 else if (!pszOut) 361 pszOut = ValueUnion.psz; 362 else 363 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many file arguments: %s", ValueUnion.psz); 364 break; 365 366 default: 367 return RTGetOptPrintError(ch, &ValueUnion); 368 } 369 } 370 if (!pszExe) 371 return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given."); 372 if (!pszOut) 373 return RTMsgErrorExit(RTEXITCODE_FAILURE, "No output file given."); 374 if (RTPathExists(pszOut)) 375 return RTMsgErrorExit(RTEXITCODE_FAILURE, "The output file '%s' exists.", pszOut); 376 377 /* 378 * Do it. 379 */ 380 /* Read & decode the PKCS#7 signature. */ 381 SIGNTOOLPKCS7EXE This; 382 RTEXITCODE rcExit = SignToolPkcs7Exe_InitFromFile(&This, pszExe, cVerbosity, enmLdrArch); 383 if (rcExit == RTEXITCODE_SUCCESS) 384 { 385 /* Find the signing certificate (ASSUMING there's only one signer and that 386 the certificate used is shipped in the set of certificates). */ 387 rcExit = RTEXITCODE_FAILURE; 388 if (This.pSignedData->SignerInfos.cItems == 1) 389 { 390 PCRTCRPKCS7ISSUERANDSERIALNUMBER pISN = &This.pSignedData->SignerInfos.papItems[0]->IssuerAndSerialNumber; 391 PCRTCRX509CERTIFICATE pCert; 392 pCert = RTCrPkcs7SetOfCerts_FindX509ByIssuerAndSerialNumber(&This.pSignedData->Certificates, 393 &pISN->Name, &pISN->SerialNumber); 394 if (pCert) 395 { 396 /* 397 * Write it out. 398 */ 399 RTFILE hFile; 400 rc = RTFileOpen(&hFile, pszOut, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE); 401 if (RT_SUCCESS(rc)) 402 { 403 uint32_t cbCert = pCert->SeqCore.Asn1Core.cbHdr + pCert->SeqCore.Asn1Core.cb; 404 rc = RTFileWrite(hFile, pCert->SeqCore.Asn1Core.uData.pu8 - pCert->SeqCore.Asn1Core.cbHdr, 405 cbCert, NULL); 406 if (RT_SUCCESS(rc)) 407 { 408 rc = RTFileClose(hFile); 409 if (RT_SUCCESS(rc)) 410 { 411 hFile = NIL_RTFILE; 412 rcExit = RTEXITCODE_SUCCESS; 413 RTMsgInfo("Successfully wrote %u bytes to '%s'", cbCert, pszOut); 414 } 415 else 416 RTMsgError("RTFileClose failed: %Rrc", rc); 417 } 418 else 419 RTMsgError("RTFileWrite failed: %Rrc", rc); 420 RTFileClose(hFile); 421 } 422 else 423 RTMsgError("Error opening '%s' for writing: %Rrc", pszOut, rc); 424 } 425 else 426 RTMsgError("Certificate not found."); 427 } 428 else 429 RTMsgError("SignerInfo count: %u", This.pSignedData->SignerInfos.cItems); 430 431 432 /* Delete the signature data. */ 433 SignToolPkcs7Exe_Delete(&This); 434 } 435 return rcExit; 436 } 437 438 439 /* 440 * The 'add-nested-exe-signature' command. 441 */ 442 static RTEXITCODE HelpAddNestedExeSignature(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel) 443 { 444 RT_NOREF_PV(enmLevel); 445 RTStrmPrintf(pStrm, "add-nested-exe-signature [-v|--verbose] <destination-exe> <source-exe>\n"); 446 return RTEXITCODE_SUCCESS; 447 } 448 449 450 static RTEXITCODE HandleAddNestedExeSignature(int cArgs, char **papszArgs) 451 { 452 /* 453 * Parse arguments. 454 */ 455 static const RTGETOPTDEF s_aOptions[] = 456 { 457 { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, 458 }; 459 460 const char *pszDst = NULL; 461 const char *pszSrc = NULL; 462 unsigned cVerbosity = 0; 463 464 RTGETOPTSTATE GetState; 465 int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); 466 AssertRCReturn(rc, RTEXITCODE_FAILURE); 467 RTGETOPTUNION ValueUnion; 468 int ch; 469 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 470 { 471 switch (ch) 472 { 473 case 'v': cVerbosity++; break; 474 case 'V': return HandleVersion(cArgs, papszArgs); 475 case 'h': return HelpExtractExeSignerCert(g_pStdOut, RTSIGNTOOLHELP_FULL); 476 477 case VINF_GETOPT_NOT_OPTION: 478 if (!pszDst) 479 pszDst = ValueUnion.psz; 480 else if (!pszSrc) 481 pszSrc = ValueUnion.psz; 482 else 483 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many file arguments: %s", ValueUnion.psz); 484 break; 485 486 default: 487 return RTGetOptPrintError(ch, &ValueUnion); 488 } 489 } 490 if (!pszDst) 491 return RTMsgErrorExit(RTEXITCODE_FAILURE, "No destination excutable given."); 492 if (!pszSrc) 493 return RTMsgErrorExit(RTEXITCODE_FAILURE, "No source executable file given."); 494 495 /* 496 * Do it. 497 */ 498 /* Read & decode the source PKCS#7 signature. */ 499 SIGNTOOLPKCS7EXE Src; 500 RTEXITCODE rcExit = SignToolPkcs7Exe_InitFromFile(&Src, pszSrc, cVerbosity); 501 if (rcExit == RTEXITCODE_SUCCESS) 502 { 503 /* Ditto for the destination PKCS#7 signature. */ 504 SIGNTOOLPKCS7EXE Dst; 505 RTEXITCODE rcExit = SignToolPkcs7Exe_InitFromFile(&Dst, pszSrc, cVerbosity); 506 if (rcExit == RTEXITCODE_SUCCESS) 507 { 508 /* Add the source to the destination as a nested signature. */ 509 //Src.pSignedData->SignerInfos.paItems 510 511 512 SignToolPkcs7Exe_Delete(&Dst); 513 } 514 SignToolPkcs7Exe_Delete(&Src); 515 } 516 517 return rcExit; 518 } 519 520 #ifndef IPRT_IN_BUILD_TOOL 521 522 /* 523 * The 'verify-exe' command. 524 */ 525 static RTEXITCODE HelpVerifyExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel) 526 { 527 RT_NOREF_PV(enmLevel); 528 RTStrmPrintf(pStrm, 529 "verify-exe [--verbose|--quiet] [--kernel] [--root <root-cert.der>] [--additional <supp-cert.der>]\n" 530 " [--type <win|osx>] <exe1> [exe2 [..]]\n"); 531 return RTEXITCODE_SUCCESS; 532 } 533 534 typedef struct VERIFYEXESTATE 535 { 536 RTCRSTORE hRootStore; 537 RTCRSTORE hKernelRootStore; 538 RTCRSTORE hAdditionalStore; 539 bool fKernel; 540 int cVerbose; 541 enum { kSignType_Windows, kSignType_OSX } enmSignType; 542 uint64_t uTimestamp; 543 RTLDRARCH enmLdrArch; 544 } VERIFYEXESTATE; 545 546 # ifdef VBOX 547 /** Certificate store load set. 548 * Declared outside HandleVerifyExe because of braindead gcc visibility crap. */ 549 struct STSTORESET 550 { 551 RTCRSTORE hStore; 552 PCSUPTAENTRY paTAs; 553 unsigned cTAs; 554 }; 555 # endif 556 557 /** 558 * @callback_method_impl{FNRTCRPKCS7VERIFYCERTCALLBACK, 559 * Standard code signing. Use this for Microsoft SPC.} 560 */ 561 static DECLCALLBACK(int) VerifyExecCertVerifyCallback(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags, 562 void *pvUser, PRTERRINFO pErrInfo) 563 { 564 VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser; 565 uint32_t cPaths = hCertPaths != NIL_RTCRX509CERTPATHS ? RTCrX509CertPathsGetPathCount(hCertPaths) : 0; 566 567 /* 568 * Dump all the paths. 569 */ 570 if (pState->cVerbose > 0) 571 { 572 for (uint32_t iPath = 0; iPath < cPaths; iPath++) 573 { 574 RTPrintf("---\n"); 575 RTCrX509CertPathsDumpOne(hCertPaths, iPath, pState->cVerbose, RTStrmDumpPrintfV, g_pStdOut); 576 *pErrInfo->pszMsg = '\0'; 577 } 578 RTPrintf("---\n"); 579 } 580 581 /* 582 * Test signing certificates normally doesn't have all the necessary 583 * features required below. So, treat them as special cases. 584 */ 585 if ( hCertPaths == NIL_RTCRX509CERTPATHS 586 && RTCrX509Name_Compare(&pCert->TbsCertificate.Issuer, &pCert->TbsCertificate.Subject) == 0) 587 { 588 RTMsgInfo("Test signed.\n"); 589 return VINF_SUCCESS; 590 } 591 592 if (hCertPaths == NIL_RTCRX509CERTPATHS) 593 RTMsgInfo("Signed by trusted certificate.\n"); 594 595 /* 596 * Standard code signing capabilites required. 597 */ 598 int rc = RTCrPkcs7VerifyCertCallbackCodeSigning(pCert, hCertPaths, fFlags, NULL, pErrInfo); 599 if ( RT_SUCCESS(rc) 600 && (fFlags & RTCRPKCS7VCC_F_SIGNED_DATA)) 601 { 602 /* 603 * If kernel signing, a valid certificate path must be anchored by the 604 * microsoft kernel signing root certificate. The only alternative is 605 * test signing. 606 */ 607 if (pState->fKernel && hCertPaths != NIL_RTCRX509CERTPATHS) 608 { 609 uint32_t cFound = 0; 610 uint32_t cValid = 0; 611 for (uint32_t iPath = 0; iPath < cPaths; iPath++) 612 { 613 bool fTrusted; 614 PCRTCRX509NAME pSubject; 615 PCRTCRX509SUBJECTPUBLICKEYINFO pPublicKeyInfo; 616 int rcVerify; 617 rc = RTCrX509CertPathsQueryPathInfo(hCertPaths, iPath, &fTrusted, NULL /*pcNodes*/, &pSubject, &pPublicKeyInfo, 618 NULL, NULL /*pCertCtx*/, &rcVerify); 619 AssertRCBreak(rc); 620 621 if (RT_SUCCESS(rcVerify)) 622 { 623 Assert(fTrusted); 624 cValid++; 625 626 /* Search the kernel signing root store for a matching anchor. */ 627 RTCRSTORECERTSEARCH Search; 628 rc = RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280(pState->hKernelRootStore, pSubject, &Search); 629 AssertRCBreak(rc); 630 PCRTCRCERTCTX pCertCtx; 631 while ((pCertCtx = RTCrStoreCertSearchNext(pState->hKernelRootStore, &Search)) != NULL) 632 { 633 PCRTCRX509SUBJECTPUBLICKEYINFO pPubKeyInfo; 634 if (pCertCtx->pCert) 635 pPubKeyInfo = &pCertCtx->pCert->TbsCertificate.SubjectPublicKeyInfo; 636 else if (pCertCtx->pTaInfo) 637 pPubKeyInfo = &pCertCtx->pTaInfo->PubKey; 638 else 639 pPubKeyInfo = NULL; 640 if (RTCrX509SubjectPublicKeyInfo_Compare(pPubKeyInfo, pPublicKeyInfo) == 0) 641 cFound++; 642 RTCrCertCtxRelease(pCertCtx); 643 } 644 645 int rc2 = RTCrStoreCertSearchDestroy(pState->hKernelRootStore, &Search); AssertRC(rc2); 646 } 647 } 648 if (RT_SUCCESS(rc) && cFound == 0) 649 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "Not valid kernel code signature."); 650 if (RT_SUCCESS(rc) && cValid != 2) 651 RTMsgWarning("%u valid paths, expected 2", cValid); 652 } 653 } 654 655 return rc; 656 } 657 658 659 /** @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA} */ 660 static DECLCALLBACK(int) VerifyExeCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature, 661 void const *pvSignature, size_t cbSignature, 662 PRTERRINFO pErrInfo, void *pvUser) 663 { 664 VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser; 665 RT_NOREF_PV(hLdrMod); RT_NOREF_PV(cbSignature); 666 667 switch (enmSignature) 668 { 669 case RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA: 670 { 671 PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature; 672 673 RTTIMESPEC ValidationTime; 674 RTTimeSpecSetSeconds(&ValidationTime, pState->uTimestamp); 675 676 /* 677 * Dump the signed data if so requested. 678 */ 679 if (pState->cVerbose) 680 RTAsn1Dump(&pContentInfo->SeqCore.Asn1Core, 0, 0, RTStrmDumpPrintfV, g_pStdOut); 681 682 683 /* 684 * Do the actual verification. Will have to modify this so it takes 685 * the authenticode policies into account. 686 */ 687 return RTCrPkcs7VerifySignedData(pContentInfo, 688 RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY 689 | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT 690 | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT, 691 pState->hAdditionalStore, pState->hRootStore, &ValidationTime, 692 VerifyExecCertVerifyCallback, pState, pErrInfo); 693 } 694 695 default: 696 return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", enmSignature); 697 } 698 } 699 700 /** Worker for HandleVerifyExe. */ 701 static RTEXITCODE HandleVerifyExeWorker(VERIFYEXESTATE *pState, const char *pszFilename, PRTERRINFOSTATIC pStaticErrInfo) 702 { 703 /* 704 * Open the executable image and verify it. 705 */ 706 RTLDRMOD hLdrMod; 707 int rc = RTLdrOpen(pszFilename, RTLDR_O_FOR_VALIDATION, pState->enmLdrArch, &hLdrMod); 708 if (RT_FAILURE(rc)) 709 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszFilename, rc); 710 711 712 rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &pState->uTimestamp, sizeof(pState->uTimestamp)); 713 if (RT_SUCCESS(rc)) 714 { 715 rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo)); 716 if (RT_SUCCESS(rc)) 717 RTMsgInfo("'%s' is valid.\n", pszFilename); 718 else if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME) 719 { 720 RTTIMESPEC Now; 721 pState->uTimestamp = RTTimeSpecGetSeconds(RTTimeNow(&Now)); 722 rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo)); 723 if (RT_SUCCESS(rc)) 724 RTMsgInfo("'%s' is valid now, but not at link time.\n", pszFilename); 725 } 726 if (RT_FAILURE(rc)) 727 RTMsgError("RTLdrVerifySignature failed on '%s': %Rrc - %s\n", pszFilename, rc, pStaticErrInfo->szMsg); 728 } 729 else 730 RTMsgError("RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on '%s': %Rrc\n", pszFilename, rc); 731 732 int rc2 = RTLdrClose(hLdrMod); 733 if (RT_FAILURE(rc2)) 734 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc2); 735 if (RT_FAILURE(rc)) 736 return rc != VERR_LDRVI_NOT_SIGNED ? RTEXITCODE_FAILURE : RTEXITCODE_SKIPPED; 737 738 return RTEXITCODE_SUCCESS; 739 } 740 741 742 static RTEXITCODE HandleVerifyExe(int cArgs, char **papszArgs) 743 { 744 RTERRINFOSTATIC StaticErrInfo; 745 746 /* Note! This code does not try to clean up the crypto stores on failure. 747 This is intentional as the code is only expected to be used in a 748 one-command-per-process environment where we do exit() upon 749 returning from this function. */ 750 751 /* 752 * Parse arguments. 753 */ 754 static const RTGETOPTDEF s_aOptions[] = 755 { 756 { "--kernel", 'k', RTGETOPT_REQ_NOTHING }, 757 { "--root", 'r', RTGETOPT_REQ_STRING }, 758 { "--additional", 'a', RTGETOPT_REQ_STRING }, 759 { "--add", 'a', RTGETOPT_REQ_STRING }, 760 { "--type", 't', RTGETOPT_REQ_STRING }, 761 { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, 762 { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, 763 }; 764 765 VERIFYEXESTATE State = 766 { 767 NIL_RTCRSTORE, NIL_RTCRSTORE, NIL_RTCRSTORE, false, false, 768 VERIFYEXESTATE::kSignType_Windows, 0, RTLDRARCH_WHATEVER 769 }; 770 int rc = RTCrStoreCreateInMem(&State.hRootStore, 0); 771 if (RT_SUCCESS(rc)) 772 rc = RTCrStoreCreateInMem(&State.hKernelRootStore, 0); 773 if (RT_SUCCESS(rc)) 774 rc = RTCrStoreCreateInMem(&State.hAdditionalStore, 0); 775 if (RT_FAILURE(rc)) 776 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error creating in-memory certificate store: %Rrc", rc); 777 778 RTGETOPTSTATE GetState; 779 rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); 780 AssertRCReturn(rc, RTEXITCODE_FAILURE); 781 RTGETOPTUNION ValueUnion; 782 int ch; 783 while ((ch = RTGetOpt(&GetState, &ValueUnion)) && ch != VINF_GETOPT_NOT_OPTION) 784 { 785 switch (ch) 786 { 787 case 'r': case 'a': 788 rc = RTCrStoreCertAddFromFile(ch == 'r' ? State.hRootStore : State.hAdditionalStore, 789 RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR, 790 ValueUnion.psz, RTErrInfoInitStatic(&StaticErrInfo)); 791 if (RT_FAILURE(rc)) 792 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error loading certificate '%s': %Rrc - %s", 793 ValueUnion.psz, rc, StaticErrInfo.szMsg); 794 if (RTErrInfoIsSet(&StaticErrInfo.Core)) 795 RTMsgWarning("Warnings loading certificate '%s': %s", ValueUnion.psz, StaticErrInfo.szMsg); 796 break; 797 798 case 't': 799 if (!strcmp(ValueUnion.psz, "win") || !strcmp(ValueUnion.psz, "windows")) 800 State.enmSignType = VERIFYEXESTATE::kSignType_Windows; 801 else if (!strcmp(ValueUnion.psz, "osx") || !strcmp(ValueUnion.psz, "apple")) 802 State.enmSignType = VERIFYEXESTATE::kSignType_OSX; 803 else 804 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown signing type: '%s'", ValueUnion.psz); 805 break; 806 807 case 'k': State.fKernel = true; break; 808 case 'v': State.cVerbose++; break; 809 case 'q': State.cVerbose = 0; break; 810 case 'V': return HandleVersion(cArgs, papszArgs); 811 case 'h': return HelpVerifyExe(g_pStdOut, RTSIGNTOOLHELP_FULL); 812 default: return RTGetOptPrintError(ch, &ValueUnion); 813 } 814 } 815 if (ch != VINF_GETOPT_NOT_OPTION) 816 return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given."); 817 818 /* 819 * Populate the certificate stores according to the signing type. 820 */ 821 #ifdef VBOX 822 unsigned cSets = 0; 823 struct STSTORESET aSets[6]; 824 #endif 825 826 switch (State.enmSignType) 827 { 828 case VERIFYEXESTATE::kSignType_Windows: 829 #ifdef VBOX 830 aSets[cSets].hStore = State.hRootStore; 831 aSets[cSets].paTAs = g_aSUPTimestampTAs; 832 aSets[cSets].cTAs = g_cSUPTimestampTAs; 833 cSets++; 834 aSets[cSets].hStore = State.hRootStore; 835 aSets[cSets].paTAs = g_aSUPSpcRootTAs; 836 aSets[cSets].cTAs = g_cSUPSpcRootTAs; 837 cSets++; 838 aSets[cSets].hStore = State.hRootStore; 839 aSets[cSets].paTAs = g_aSUPNtKernelRootTAs; 840 aSets[cSets].cTAs = g_cSUPNtKernelRootTAs; 841 cSets++; 842 aSets[cSets].hStore = State.hKernelRootStore; 843 aSets[cSets].paTAs = g_aSUPNtKernelRootTAs; 844 aSets[cSets].cTAs = g_cSUPNtKernelRootTAs; 845 cSets++; 846 #endif 847 break; 848 849 case VERIFYEXESTATE::kSignType_OSX: 850 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Mac OS X executable signing is not implemented."); 851 } 852 853 #ifdef VBOX 854 for (unsigned i = 0; i < cSets; i++) 855 for (unsigned j = 0; j < aSets[i].cTAs; j++) 856 { 857 rc = RTCrStoreCertAddEncoded(aSets[i].hStore, RTCRCERTCTX_F_ENC_TAF_DER, aSets[i].paTAs[j].pch, 858 aSets[i].paTAs[j].cb, RTErrInfoInitStatic(&StaticErrInfo)); 859 if (RT_FAILURE(rc)) 860 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTCrStoreCertAddEncoded failed (%u/%u): %s", 861 i, j, StaticErrInfo.szMsg); 862 } 863 #endif 864 865 /* 866 * Do it. 867 */ 868 RTEXITCODE rcExit; 869 for (;;) 870 { 871 rcExit = HandleVerifyExeWorker(&State, ValueUnion.psz, &StaticErrInfo); 872 if (rcExit != RTEXITCODE_SUCCESS) 873 break; 874 875 /* 876 * Next file 877 */ 878 ch = RTGetOpt(&GetState, &ValueUnion); 879 if (ch == 0) 880 break; 881 if (ch != VINF_GETOPT_NOT_OPTION) 882 { 883 rcExit = RTGetOptPrintError(ch, &ValueUnion); 884 break; 885 } 886 } 887 888 /* 889 * Clean up. 890 */ 891 uint32_t cRefs; 892 cRefs = RTCrStoreRelease(State.hRootStore); Assert(cRefs == 0); 893 cRefs = RTCrStoreRelease(State.hKernelRootStore); Assert(cRefs == 0); 894 cRefs = RTCrStoreRelease(State.hAdditionalStore); Assert(cRefs == 0); 895 896 return rcExit; 897 } 898 899 #endif /* !IPRT_IN_BUILD_TOOL */ 900 #ifndef IPRT_IN_BUILD_TOOL 901 902 /* 903 * The 'show-exe' command. 904 */ 905 static RTEXITCODE HelpShowExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel) 906 { 907 RT_NOREF_PV(enmLevel); 908 RTStrmPrintf(pStrm, 909 "show-exe [--verbose|-v] [--quiet|-q] <exe1> [exe2 [..]]\n"); 910 return RTEXITCODE_SUCCESS; 911 } 912 913 914 /** 915 * Decodes the PKCS #7 blob pointed to by pThis->pbBuf. 916 * 917 * @returns IPRT status code. 918 * @param pThis The show exe instance data. 919 */ 920 static int HandleShowExeWorkerPkcs7Decode(PSHOWEXEPKCS7 pThis) 921 { 922 RTERRINFOSTATIC ErrInfo; 923 RTASN1CURSORPRIMARY PrimaryCursor; 924 RTAsn1CursorInitPrimary(&PrimaryCursor, pThis->pbBuf, (uint32_t)pThis->cbBuf, RTErrInfoInitStatic(&ErrInfo), 925 &g_RTAsn1DefaultAllocator, 0, "WinCert"); 926 927 int rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &pThis->ContentInfo, "CI"); 928 if (RT_SUCCESS(rc)) 929 { 930 if (RTCrPkcs7ContentInfo_IsSignedData(&pThis->ContentInfo)) 931 { 932 pThis->pSignedData = pThis->ContentInfo.u.pSignedData; 933 934 /* 935 * Decode the authenticode bits. 936 */ 937 if (!strcmp(pThis->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID)) 938 { 939 pThis->pIndData = pThis->pSignedData->ContentInfo.u.pIndirectDataContent; 940 Assert(pThis->pIndData); 941 942 /* 943 * Check that things add up. 944 */ 945 rc = RTCrPkcs7SignedData_CheckSanity(pThis->pSignedData, 946 RTCRPKCS7SIGNEDDATA_SANITY_F_AUTHENTICODE 947 | RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH 948 | RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT, 949 RTErrInfoInitStatic(&ErrInfo), "SD"); 950 if (RT_FAILURE(rc)) 951 RTMsgError("PKCS#7 sanity check failed for '%s': %Rrc - %s\n", pThis->pszFilename, rc, ErrInfo.szMsg); 952 if (RT_SUCCESS(rc)) 953 { 954 rc = RTCrSpcIndirectDataContent_CheckSanityEx(pThis->pIndData, 955 pThis->pSignedData, 956 RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH, 957 RTErrInfoInitStatic(&ErrInfo)); 958 if (RT_FAILURE(rc)) 959 RTMsgError("SPC indirect data content sanity check failed for '%s': %Rrc - %s\n", 960 pThis->pszFilename, rc, ErrInfo.szMsg); 961 } 962 } 963 else 964 RTMsgError("Unexpected the signed content in '%s': %s (expected %s)", pThis->pszFilename, 965 pThis->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID); 966 } 967 else 968 RTMsgError("PKCS#7 content is inside '%s' is not 'signedData': %s\n", 969 pThis->pszFilename, pThis->ContentInfo.ContentType.szObjId); 970 } 971 else 972 RTMsgError("RTCrPkcs7ContentInfo_DecodeAsn1 failed on '%s': %Rrc - %s\n", pThis->pszFilename, rc, ErrInfo.szMsg); 973 return rc; 974 } 975 976 977 /** 726 978 * Display an object ID. 727 979 * … … 802 1054 else 803 1055 RTPrintf("%s ObjId[%u]: ", pThis->szPrefix, i); 804 HandleShowExeWorkerDisplayObjIdSimple(pThis, &pAttr->uValues.pObjIds->paItems[i], "\n");1056 HandleShowExeWorkerDisplayObjIdSimple(pThis, pAttr->uValues.pObjIds->papItems[i], "\n"); 805 1057 } 806 1058 break; … … 812 1064 for (unsigned i = 0; i < pAttr->uValues.pObjIdSeqs->cItems; i++) 813 1065 { 814 uint32_t const cObjIds = pAttr->uValues.pObjIdSeqs->pa Items[i].cItems;1066 uint32_t const cObjIds = pAttr->uValues.pObjIdSeqs->papItems[i]->cItems; 815 1067 for (unsigned j = 0; j < cObjIds; j++) 816 1068 { … … 821 1073 if (cObjIds != 1) 822 1074 RTPrintf(" ObjId[%u]: ", j); 823 HandleShowExeWorkerDisplayObjIdSimple(pThis, &pAttr->uValues.pObjIdSeqs->paItems[i].paItems[i], "\n");1075 HandleShowExeWorkerDisplayObjIdSimple(pThis, pAttr->uValues.pObjIdSeqs->papItems[i]->papItems[i], "\n"); 824 1076 } 825 1077 } … … 832 1084 for (unsigned i = 0; i < pAttr->uValues.pOctetStrings->cItems; i++) 833 1085 { 834 PCRTASN1OCTETSTRING pOctetString = &pAttr->uValues.pOctetStrings->paItems[i];1086 PCRTASN1OCTETSTRING pOctetString = pAttr->uValues.pOctetStrings->papItems[i]; 835 1087 uint32_t cbContent = pOctetString->Asn1Core.cb; 836 1088 if (cbContent > 0 && (cbContent <= 128 || pThis->cVerbosity >= 2)) … … 879 1131 offPrefix2 += RTStrPrintf(&pThis->szPrefix[offPrefix], sizeof(pThis->szPrefix) - offPrefix, " "); 880 1132 // offPrefix2 += RTStrPrintf(&pThis->szPrefix[offPrefix], sizeof(pThis->szPrefix) - offPrefix, "NestedSig: ", i); 881 PCRTCRPKCS7CONTENTINFO pContentInfo = &pAttr->uValues.pContentInfos->paItems[i];1133 PCRTCRPKCS7CONTENTINFO pContentInfo = pAttr->uValues.pContentInfos->papItems[i]; 882 1134 int rc2; 883 1135 if (RTCrPkcs7ContentInfo_IsSignedData(pContentInfo)) … … 960 1212 "MonikerAttrib[%u]: ", i); 961 1213 962 switch (pData->pa Items[i].enmType)1214 switch (pData->papItems[i]->enmType) 963 1215 { 964 1216 case RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V2: 965 1217 case RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1: 966 1218 { 967 PCRTCRSPCSERIALIZEDPAGEHASHES pPgHashes = pData->pa Items[i].u.pPageHashes;968 uint32_t const cbHash = pData->pa Items[i].enmType1219 PCRTCRSPCSERIALIZEDPAGEHASHES pPgHashes = pData->papItems[i]->u.pPageHashes; 1220 uint32_t const cbHash = pData->papItems[i]->enmType 969 1221 == RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1 970 1222 ? 160/8 /*SHA-1*/ : 256/8 /*SHA-256*/; … … 972 1224 973 1225 RTPrintf("%sPage Hashes version %u - %u pages (%u bytes total)\n", pThis->szPrefix, 974 pData->pa Items[i].enmType1226 pData->papItems[i]->enmType 975 1227 == RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1 ? 1 : 2, 976 1228 cPages, pPgHashes->RawData.Asn1Core.cb); … … 1006 1258 1007 1259 case RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_UNKNOWN: 1008 HandleShowExeWorkerDisplayObjIdSimple(pThis, &pData->pa Items[i].Type, "\n");1260 HandleShowExeWorkerDisplayObjIdSimple(pThis, &pData->papItems[i]->Type, "\n"); 1009 1261 break; 1010 1262 case RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_NOT_PRESENT: … … 1012 1264 break; 1013 1265 default: 1014 RTPrintf("%senmType=%d!\n", pThis->szPrefix, pData->pa Items[i].enmType);1266 RTPrintf("%senmType=%d!\n", pThis->szPrefix, pData->papItems[i]->enmType); 1015 1267 break; 1016 1268 } … … 1099 1351 for (unsigned i = 0; i < pSignedData->DigestAlgorithms.cItems; i++) 1100 1352 { 1101 PCRTCRX509ALGORITHMIDENTIFIER pAlgoId = &pSignedData->DigestAlgorithms.paItems[i];1353 PCRTCRX509ALGORITHMIDENTIFIER pAlgoId = pSignedData->DigestAlgorithms.papItems[i]; 1102 1354 const char *pszDigestType = RTCrDigestTypeToName(RTCrX509AlgorithmIdentifier_QueryDigestType(pAlgoId)); 1103 1355 if (!pszDigestType) … … 1121 1373 } 1122 1374 else 1123 RTPrintf("%s ContentType: %s\n", pThis->szPrefix, pSignedData->ContentInfo.ContentType.szObjId);1375 HandleShowExeWorkerDisplayObjId(pThis, &pSignedData->ContentInfo.ContentType, " ContentType: ", " - not implemented.\n"); 1124 1376 1125 1377 /* 1126 1378 * Display certificates (Certificates). 1127 1379 */ 1380 if (pSignedData->Certificates.cItems > 0) 1381 RTPrintf("%s Certificates: %u\n", pThis->szPrefix, pSignedData->Certificates.cItems); 1382 /** @todo display certificates. */ 1383 1384 if (pSignedData->Crls.cb > 0) 1385 RTPrintf("%s CRLs: %u bytes\n", pThis->szPrefix, pSignedData->Crls.cb); 1128 1386 1129 1387 /* … … 1134 1392 for (unsigned i = 0; i < cSigInfos; i++) 1135 1393 { 1136 PRTCRPKCS7SIGNERINFO pSigInfo = &pSignedData->SignerInfos.paItems[i];1394 PRTCRPKCS7SIGNERINFO pSigInfo = pSignedData->SignerInfos.papItems[i]; 1137 1395 size_t offPrefix2 = offPrefix; 1138 1396 if (cSigInfos != 1) … … 1170 1428 for (unsigned j = 0; j < pSigInfo->AuthenticatedAttributes.cItems; j++) 1171 1429 { 1172 PRTCRPKCS7ATTRIBUTE pAttr = &pSigInfo->AuthenticatedAttributes.paItems[j];1430 PRTCRPKCS7ATTRIBUTE pAttr = pSigInfo->AuthenticatedAttributes.papItems[j]; 1173 1431 size_t offPrefix3 = offPrefix2 + RTStrPrintf(&pThis->szPrefix[offPrefix2], sizeof(pThis->szPrefix) - offPrefix2, 1174 1432 " AuthAttrib[%u]: ", j); … … 1186 1444 for (unsigned j = 0; j < pSigInfo->UnauthenticatedAttributes.cItems; j++) 1187 1445 { 1188 PRTCRPKCS7ATTRIBUTE pAttr = &pSigInfo->UnauthenticatedAttributes.paItems[j];1446 PRTCRPKCS7ATTRIBUTE pAttr = pSigInfo->UnauthenticatedAttributes.papItems[j]; 1189 1447 size_t offPrefix3 = offPrefix2 + RTStrPrintf(&pThis->szPrefix[offPrefix2], sizeof(pThis->szPrefix) - offPrefix2, 1190 1448 " UnauthAttrib[%u]: ", j); … … 1212 1470 static RTEXITCODE HandleShowExeWorker(const char *pszFilename, unsigned cVerbosity, RTLDRARCH enmLdrArch) 1213 1471 { 1214 /* 1215 * Open the image and check if it's signed. 1216 */ 1217 RTLDRMOD hLdrMod; 1218 int rc = RTLdrOpen(pszFilename, RTLDR_O_FOR_VALIDATION, enmLdrArch, &hLdrMod); 1219 if (RT_FAILURE(rc)) 1220 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszFilename, rc); 1221 1222 bool fIsSigned = false; 1223 rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_IS_SIGNED, &fIsSigned, sizeof(fIsSigned)); 1224 if (RT_SUCCESS(rc) && fIsSigned) 1225 { 1226 /* 1227 * Query the PKCS#7 data (assuming M$ style signing) and hand it to a worker. 1228 */ 1229 size_t cbActual = 0; 1230 size_t cbBuf = _64K; 1231 void *pvBuf = RTMemAllocZ(cbBuf); 1232 if (pvBuf) 1233 { 1234 rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbActual); 1235 if (rc == VERR_BUFFER_OVERFLOW) 1236 { 1237 RTMemFree(pvBuf); 1238 cbBuf = cbActual; 1239 pvBuf = RTMemAllocZ(cbActual); 1240 if (pvBuf) 1241 rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbActual); 1242 else 1243 rc = VERR_NO_MEMORY; 1244 } 1245 } 1246 else 1247 rc = VERR_NO_MEMORY; 1248 if (RT_SUCCESS(rc)) 1249 { 1250 SHOWEXEPKCS7 This; 1251 RT_ZERO(This); 1252 This.pbBuf = (uint8_t const *)pvBuf; 1253 This.cbBuf = cbActual; 1254 This.cVerbosity = cVerbosity; 1255 This.pszFilename = pszFilename; 1256 This.hLdrMod = hLdrMod; 1257 rc = HandleShowExeWorkerPkcs7Decode(&This); 1258 if (RT_SUCCESS(rc)) 1259 rc = HandleShowExeWorkerPkcs7Display(&This, This.pSignedData, 0); 1260 RTCrPkcs7ContentInfo_Delete(&This.ContentInfo); 1261 } 1262 else 1263 RTMsgError("RTLdrQueryPropEx/RTLDRPROP_PKCS7_SIGNED_DATA failed on '%s': %Rrc\n", pszFilename, rc); 1264 RTMemFree(pvBuf); 1265 } 1266 else if (RT_SUCCESS(rc)) 1267 RTMsgInfo("'%s': not signed\n", pszFilename); 1268 else 1269 RTMsgError("RTLdrQueryProp/RTLDRPROP_IS_SIGNED failed on '%s': %Rrc\n", pszFilename, rc); 1270 1271 int rc2 = RTLdrClose(hLdrMod); 1272 if (RT_FAILURE(rc2)) 1273 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc2); 1274 if (RT_FAILURE(rc)) 1275 return rc != VERR_LDRVI_NOT_SIGNED ? RTEXITCODE_FAILURE : RTEXITCODE_SKIPPED; 1276 1277 return RTEXITCODE_SUCCESS; 1472 SHOWEXEPKCS7 This; 1473 RT_ZERO(This); 1474 This.cVerbosity = cVerbosity; 1475 1476 RTEXITCODE rcExit = SignToolPkcs7Exe_InitFromFile(&This, pszFilename, cVerbosity, enmLdrArch); 1477 if (rcExit == RTEXITCODE_SUCCESS) 1478 { 1479 int rc = HandleShowExeWorkerPkcs7Display(&This, This.pSignedData, 0); 1480 if (RT_FAILURE(rc)) 1481 rcExit = RTEXITCODE_FAILURE; 1482 SignToolPkcs7Exe_Delete(&This); 1483 } 1484 1485 return rcExit; 1278 1486 } 1279 1487 … … 1599 1807 { "extract-exe-signer-cert", HandleExtractExeSignerCert, HelpExtractExeSignerCert }, 1600 1808 #ifndef IPRT_IN_BUILD_TOOL 1809 { "add-nested-exe-signature", HandleAddNestedExeSignature, HelpAddNestedExeSignature }, 1601 1810 { "verify-exe", HandleVerifyExe, HelpVerifyExe }, 1602 1811 { "show-exe", HandleShowExe, HelpShowExe },
Note:
See TracChangeset
for help on using the changeset viewer.