VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/crypto/spc-sanity.cpp@ 64883

Last change on this file since 64883 was 64883, checked in by vboxsync, 8 years ago

IPRT/ASN.1: Refactored array handling (SET OF, SEQUENCE OF) to use a pointer array instead of an object instance array. The old approach would move objects around in memory after they'd be initialized/decoded, making certain core optimziations involving pointers to object members impossible, as well as causing potentially causing trouble when modifying structures that takes down pointers after decoding. Fixed validation bug in rtCrX509Name_CheckSanityExtra where it didn't check that the RDNs had subitems but instead checked the parent twice (slight risk).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.3 KB
Line 
1/* $Id: spc-sanity.cpp 64883 2016-12-15 15:26:20Z vboxsync $ */
2/** @file
3 * IPRT - Crypto - Microsoft SPC / Authenticode, Sanity Checkers.
4 */
5
6/*
7 * Copyright (C) 2006-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include "internal/iprt.h"
32#include <iprt/crypto/spc.h>
33
34#include <iprt/assert.h>
35#include <iprt/err.h>
36#include <iprt/uuid.h>
37
38#include "spc-internal.h"
39
40
41RTDECL(int) RTCrSpcIndirectDataContent_CheckSanityEx(PCRTCRSPCINDIRECTDATACONTENT pIndData,
42 PCRTCRPKCS7SIGNEDDATA pSignedData,
43 uint32_t fFlags,
44 PRTERRINFO pErrInfo)
45{
46 /*
47 * Match up the digest algorithms (page 8, v1.0).
48 */
49 if (pSignedData->SignerInfos.cItems != 1)
50 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_NOT_EXACTLY_ONE_SIGNER_INFOS,
51 "SpcIndirectDataContent expects SignedData to have exactly one SignerInfos entries, found: %u",
52 pSignedData->SignerInfos.cItems);
53 if (pSignedData->DigestAlgorithms.cItems != 1)
54 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_NOT_EXACTLY_ONE_DIGEST_ALGO,
55 "SpcIndirectDataContent expects SignedData to have exactly one DigestAlgorithms entries, found: %u",
56 pSignedData->DigestAlgorithms.cItems);
57
58 if (RTCrX509AlgorithmIdentifier_Compare(&pIndData->DigestInfo.DigestAlgorithm, /** @todo not entirely sure about this check... */
59 &pSignedData->SignerInfos.papItems[0]->DigestAlgorithm) != 0)
60 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_SIGNED_IND_DATA_DIGEST_ALGO_MISMATCH,
61 "SpcIndirectDataContent DigestInfo and SignerInfos algorithms mismatch: %s vs %s",
62 pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId,
63 pSignedData->SignerInfos.papItems[0]->DigestAlgorithm.Algorithm.szObjId);
64
65 if (RTCrX509AlgorithmIdentifier_Compare(&pIndData->DigestInfo.DigestAlgorithm,
66 pSignedData->DigestAlgorithms.papItems[0]) != 0)
67 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_IND_DATA_DIGEST_ALGO_NOT_IN_DIGEST_ALGOS,
68 "SpcIndirectDataContent DigestInfo and SignedData.DigestAlgorithms[0] mismatch: %s vs %s",
69 pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId,
70 pSignedData->DigestAlgorithms.papItems[0]->Algorithm.szObjId);
71
72 if (fFlags & RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH)
73 {
74 if (RTCrX509AlgorithmIdentifier_QueryDigestType(&pIndData->DigestInfo.DigestAlgorithm) == RTDIGESTTYPE_INVALID)
75 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_UNKNOWN_DIGEST_ALGO,
76 "SpcIndirectDataContent DigestAlgortihm is not known: %s",
77 pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId);
78 }
79
80 uint32_t cbDigest = RTCrX509AlgorithmIdentifier_QueryDigestSize(&pIndData->DigestInfo.DigestAlgorithm);
81 if ( pIndData->DigestInfo.Digest.Asn1Core.cb != cbDigest
82 && (cbDigest != UINT32_MAX || (fFlags & RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH)))
83 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_IND_DATA_DIGEST_SIZE_MISMATCH,
84 "SpcIndirectDataContent Digest size mismatch with algorithm: %u, expected %u (%s)",
85 pIndData->DigestInfo.Digest.Asn1Core.cb, cbDigest,
86 pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId);
87
88 /*
89 * Data.
90 */
91 if (fFlags & RTCRSPCINDIRECTDATACONTENT_SANITY_F_PE_IMAGE)
92 {
93 if ( pIndData->Data.enmType != RTCRSPCAAOVTYPE_PE_IMAGE_DATA
94 || RTAsn1ObjId_CompareWithString(&pIndData->Data.Type, RTCRSPCPEIMAGEDATA_OID) != 0)
95 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_EXPECTED_PE_IMAGE_DATA,
96 "SpcIndirectDataContent.Data.Type is %s, expected %s (SpcPeImageData) [enmType=%d]",
97 pIndData->Data.Type.szObjId, RTCRSPCPEIMAGEDATA_OID, pIndData->Data.enmType);
98 if ( pIndData->Data.uValue.pPeImage
99 || !RTCrSpcPeImageData_IsPresent(pIndData->Data.uValue.pPeImage) )
100 return RTErrInfoSet(pErrInfo, VERR_CR_SPC_PEIMAGE_DATA_NOT_PRESENT,
101 "SpcIndirectDataContent.Data.uValue/PEImage is missing");
102
103 if ( pIndData->Data.uValue.pPeImage->T0.File.enmChoice == RTCRSPCLINKCHOICE_MONIKER
104 && RTCrSpcSerializedObject_IsPresent(pIndData->Data.uValue.pPeImage->T0.File.u.pMoniker) )
105 {
106 PCRTCRSPCSERIALIZEDOBJECT pObj = pIndData->Data.uValue.pPeImage->T0.File.u.pMoniker;
107
108 if (pObj->Uuid.Asn1Core.cb != sizeof(RTUUID))
109 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_BAD_MONIKER_UUID,
110 "SpcIndirectDataContent...MonikerT1.Uuid incorrect size: %u, expected %u.",
111 pObj->Uuid.Asn1Core.cb, sizeof(RTUUID));
112 if (RTUuidCompareStr(pObj->Uuid.Asn1Core.uData.pUuid, RTCRSPCSERIALIZEDOBJECT_UUID_STR) != 0)
113 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_UNKNOWN_MONIKER_UUID,
114 "SpcIndirectDataContent...MonikerT1.Uuid mismatch: %RTuuid, expected %s.",
115 pObj->Uuid.Asn1Core.uData.pUuid, RTCRSPCSERIALIZEDOBJECT_UUID_STR);
116
117 if (pObj->enmType != RTCRSPCSERIALIZEDOBJECTTYPE_ATTRIBUTES)
118 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_BAD_MONIKER_CHOICE,
119 "SpcIndirectDataContent...pMoniker->enmType=%d, expected %d.",
120 pObj->enmType, RTCRSPCSERIALIZEDOBJECTTYPE_ATTRIBUTES);
121 if (!pObj->u.pData)
122 return RTErrInfoSet(pErrInfo, VERR_CR_SPC_MONIKER_BAD_DATA,
123 "SpcIndirectDataContent...pMoniker->pData is NULL.");
124
125 uint32_t cPageHashTabs = 0;
126 for (uint32_t i = 0; i < pObj->u.pData->cItems; i++)
127 {
128 PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttr = pObj->u.pData->papItems[i];
129 if ( RTAsn1ObjId_CompareWithString(&pAttr->Type, RTCRSPC_PE_IMAGE_HASHES_V1_OID) == 0
130 || RTAsn1ObjId_CompareWithString(&pAttr->Type, RTCRSPC_PE_IMAGE_HASHES_V2_OID) == 0 )
131 {
132 cPageHashTabs++;
133 AssertPtr(pAttr->u.pPageHashes->pData);
134 }
135 else
136 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_PEIMAGE_UNKNOWN_ATTRIBUTE,
137 "SpcIndirectDataContent...MonikerT1 unknown attribute %u: %s.",
138 i, pAttr->Type.szObjId);
139 }
140 if (cPageHashTabs > 0)
141 return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_PEIMAGE_MULTIPLE_HASH_TABS,
142 "SpcIndirectDataContent...MonikerT1 multiple page hash attributes (%u).", cPageHashTabs);
143
144 }
145 else if ( pIndData->Data.uValue.pPeImage->T0.File.enmChoice == RTCRSPCLINKCHOICE_FILE
146 && RTCrSpcString_IsPresent(&pIndData->Data.uValue.pPeImage->T0.File.u.pT2->File) )
147 {
148 /* Could check for "<<<Obsolete>>>" here, but it's really irrelevant. */
149 }
150 else if ( pIndData->Data.uValue.pPeImage->T0.File.enmChoice == RTCRSPCLINKCHOICE_URL
151 && RTAsn1String_IsPresent(pIndData->Data.uValue.pPeImage->T0.File.u.pUrl) )
152 return RTErrInfoSet(pErrInfo, VERR_CR_SPC_PEIMAGE_URL_UNEXPECTED,
153 "SpcIndirectDataContent.Data.uValue.pPeImage->File is an URL, expected object Moniker or File.");
154 else
155 return RTErrInfoSet(pErrInfo, VERR_CR_SPC_PEIMAGE_NO_CONTENT,
156 "SpcIndirectDataContent.Data.uValue.pPeImage->File has no content");
157 }
158
159 return VINF_SUCCESS;
160}
161
162
163/*
164 * Generate the standard core code.
165 */
166#include <iprt/asn1-generator-sanity.h>
167
Note: See TracBrowser for help on using the repository browser.

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