Changeset 95598 in vbox
- Timestamp:
- Jul 12, 2022 2:27:37 AM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/tools/RTSignTool.cpp
r95583 r95598 48 48 #include <iprt/crypto/applecodesign.h> 49 49 #include <iprt/crypto/digest.h> 50 #include <iprt/crypto/key.h> 50 51 #include <iprt/crypto/x509.h> 51 52 #include <iprt/crypto/pkcs7.h> … … 59 60 # include <iprt/win/imagehlp.h> 60 61 #endif 62 63 64 /********************************************************************************************************************************* 65 * Defined Constants And Macros * 66 *********************************************************************************************************************************/ 67 #define OPT_TIMESTAMP_CERT_FILE 1000 68 #define OPT_TIMESTAMP_KEY_FILE 1001 69 #define OPT_TIMESTAMP_TYPE 1002 70 #define OPT_TIMESTAMP_DATE 1003 71 #define OPT_TIMESTAMP_YEAR 1004 61 72 62 73 … … 335 346 336 347 /** 348 * Helper that makes sure the UnauthenticatedAttributes are present in the given 349 * SignerInfo structure. 350 * 351 * Call this before trying to modify the array. 352 * 353 * @returns RTEXITCODE_SUCCESS on success, RTEXITCODE_FAILURE with error already 354 * displayed on failure. 355 * @param pSignerInfo The SignerInfo structure in question. 356 */ 357 static RTEXITCODE SignToolPkcs7_EnsureUnauthenticatedAttributesPresent(PRTCRPKCS7SIGNERINFO pSignerInfo) 358 { 359 if (pSignerInfo->UnauthenticatedAttributes.cItems == 0) 360 { 361 /* HACK ALERT! Invent ASN.1 setters/whatever for members to replace this mess. */ 362 363 if (pSignerInfo->AuthenticatedAttributes.cItems == 0) 364 return RTMsgErrorExit(RTEXITCODE_FAILURE, "No authenticated or unauthenticated attributes! Sorry, no can do."); 365 366 Assert(pSignerInfo->UnauthenticatedAttributes.SetCore.Asn1Core.uTag == 0); 367 int rc = RTAsn1SetCore_Init(&pSignerInfo->UnauthenticatedAttributes.SetCore, 368 pSignerInfo->AuthenticatedAttributes.SetCore.Asn1Core.pOps); 369 if (RT_FAILURE(rc)) 370 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTAsn1SetCore_Init failed: %Rrc", rc); 371 pSignerInfo->UnauthenticatedAttributes.SetCore.Asn1Core.uTag = 1; 372 pSignerInfo->UnauthenticatedAttributes.SetCore.Asn1Core.fClass = ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_CONSTRUCTED; 373 RTAsn1MemInitArrayAllocation(&pSignerInfo->UnauthenticatedAttributes.Allocation, 374 pSignerInfo->AuthenticatedAttributes.Allocation.pAllocator, 375 sizeof(**pSignerInfo->UnauthenticatedAttributes.papItems)); 376 } 377 return RTEXITCODE_SUCCESS; 378 } 379 380 381 /** 337 382 * Adds the @a pSrc signature as a nested signature. 338 383 * … … 349 394 { 350 395 PRTCRPKCS7SIGNERINFO pSignerInfo = pThis->pSignedData->SignerInfos.papItems[0]; 351 int rc;352 396 353 397 /* 354 398 * Deal with UnauthenticatedAttributes being absent before trying to append to the array. 355 399 */ 356 if (pSignerInfo->UnauthenticatedAttributes.cItems == 0) 357 { 358 /* HACK ALERT! Invent ASN.1 setters/whatever for members to replace this mess. */ 359 360 if (pSignerInfo->AuthenticatedAttributes.cItems == 0) 361 return RTMsgErrorExit(RTEXITCODE_FAILURE, "No authenticated or unauthenticated attributes! Sorry, no can do."); 362 363 Assert(pSignerInfo->UnauthenticatedAttributes.SetCore.Asn1Core.uTag == 0); 364 rc = RTAsn1SetCore_Init(&pSignerInfo->UnauthenticatedAttributes.SetCore, 365 pSignerInfo->AuthenticatedAttributes.SetCore.Asn1Core.pOps); 366 if (RT_FAILURE(rc)) 367 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTAsn1SetCore_Init failed: %Rrc", rc); 368 pSignerInfo->UnauthenticatedAttributes.SetCore.Asn1Core.uTag = 1; 369 pSignerInfo->UnauthenticatedAttributes.SetCore.Asn1Core.fClass = ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_CONSTRUCTED; 370 RTAsn1MemInitArrayAllocation(&pSignerInfo->UnauthenticatedAttributes.Allocation, 371 pSignerInfo->AuthenticatedAttributes.Allocation.pAllocator, 372 sizeof(**pSignerInfo->UnauthenticatedAttributes.papItems)); 373 } 400 RTEXITCODE rcExit = SignToolPkcs7_EnsureUnauthenticatedAttributesPresent(pSignerInfo); 401 if (rcExit != RTEXITCODE_SUCCESS) 402 return rcExit; 374 403 375 404 /* 376 405 * Find or add an unauthenticated attribute for nested signatures. 377 406 */ 378 rc = VERR_NOT_FOUND;407 int rc = VERR_NOT_FOUND; 379 408 PRTCRPKCS7ATTRIBUTE pAttr = NULL; 380 409 int32_t iPos = pSignerInfo->UnauthenticatedAttributes.cItems; … … 496 525 * Worker for recursively searching for MS nested signatures and signer infos. 497 526 * 498 * @returns Pointer to the signer info corresponding to @a i Signature. NULL if499 * not found.527 * @returns Pointer to the signer info corresponding to @a iReqSignature. NULL 528 * if not found. 500 529 * @param pSignedData The signature to search. 501 530 * @param piNextSignature Pointer to the variable keeping track of the next … … 503 532 * @param iReqSignature The request signature number. 504 533 * @param ppSignedData Where to return the signature data structure. 534 * Optional. 505 535 */ 506 536 static PRTCRPKCS7SIGNERINFO SignToolPkcs7_FindNestedSignatureByIndexWorker(PRTCRPKCS7SIGNEDDATA pSignedData, … … 515 545 if (*piNextSignature == iReqSignature) 516 546 { 517 *ppSignedData = pSignedData; 547 if (ppSignedData) 548 *ppSignedData = pSignedData; 518 549 return pSignerInfo; 519 550 } … … 547 578 * Locates the given nested signature. 548 579 * 549 * @returns Pointer to the signer info corresponding to @a i Signature. NULL if550 * not found.580 * @returns Pointer to the signer info corresponding to @a iReqSignature. NULL 581 * if not found. 551 582 * @param pThis The PKCS\#7 structure to search. 552 583 * @param iReqSignature The requested signature number. … … 882 913 } 883 914 884 885 886 /* 887 * The 'extract-exe-signer-cert' command. 888 */ 915 #ifndef IPRT_IN_BUILD_TOOL 916 917 static RTEXITCODE AddAuthAttribsForTimestamp(PRTCRPKCS7ATTRIBUTES pAuthAttribs, bool fTimestampTypeOld, 918 RTTIMESPEC SigningTime, PCRTCRX509CERTIFICATE pTimestampCert) 919 { 920 /* 921 * Signing time. For the old-style timestamps, Symantec used ASN.1 UTC TIME. 922 * start -vv vv=ASN1_TAG_UTC_TIME 923 * 00000187d6a65fd0/23b0: 0d 01 09 05 31 0f 17 0d-31 36 31 30 30 35 30 37 ....1...16100507 924 * 00000187d6a65fe0/23c0: 35 30 33 30 5a 30 23 06-09 2a 86 48 86 f7 0d 01 5030Z0#..*.H.... 925 * ^^- end 2016-10-05T07:50:30.000000000Z (161005075030Z) 926 */ 927 int32_t iPos = RTCrPkcs7Attributes_Append(pAuthAttribs); 928 if (iPos < 0) 929 return RTMsgErrorExitFailure("RTCrPkcs7Attributes_Append failed: %Rrc", iPos); 930 931 /* Create the attrib and its sub-set of timestamps. */ 932 PRTCRPKCS7ATTRIBUTE pAttr = pAuthAttribs->papItems[iPos]; 933 int rc = RTAsn1ObjId_InitFromString(&pAttr->Type, RTCR_PKCS9_ID_SIGNING_TIME_OID, pAttr->Allocation.pAllocator); 934 if (RT_FAILURE(rc)) 935 return RTMsgErrorExitFailure("RTAsn1ObjId_InitFromString/RTCR_PKCS9_ID_SIGNING_TIME_OID failed: %Rrc", rc); 936 937 /** @todo Generalize the Type + enmType DYN stuff and generate setters. */ 938 Assert(pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_NOT_PRESENT); 939 Assert(pAttr->uValues.pContentInfos == NULL); 940 pAttr->enmType = RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME; 941 rc = RTAsn1MemAllocZ(&pAttr->Allocation, (void **)&pAttr->uValues.pSigningTime, sizeof(*pAttr->uValues.pSigningTime)); 942 if (RT_FAILURE(rc)) 943 return RTMsgErrorExitFailure("RTAsn1MemAllocZ failed: %Rrc", rc); 944 945 rc = RTAsn1SetOfTimes_Init(pAttr->uValues.pSigningTime, pAttr->Allocation.pAllocator); 946 if (RT_FAILURE(rc)) 947 return RTMsgErrorExitFailure("RTCrPkcs7ContentInfos_Init failed: %Rrc", rc); 948 949 /* Create the timestamp. */ 950 iPos = RTAsn1SetOfTimes_Append(pAttr->uValues.pSigningTime); 951 if (iPos < 0) 952 return RTMsgErrorExitFailure("RTCrPkcs7SigningTimes_Append failed: %Rrc", iPos); 953 954 PRTASN1TIME pTime = pAttr->uValues.pSigningTime->papItems[iPos]; 955 rc = RTAsn1Time_SetTimeSpec(pTime, pAttr->Allocation.pAllocator, &SigningTime); 956 if (RT_FAILURE(rc)) 957 return RTMsgErrorExitFailure("RTAsn1Time_SetTimeSpec failed: %Rrc", rc); 958 959 /* 960 * More later if we want to support fTimestampTypeOld = false perhaps? 961 */ 962 Assert(fTimestampTypeOld); 963 RT_NOREF(fTimestampTypeOld, pTimestampCert); 964 965 return RTEXITCODE_SUCCESS; 966 } 967 968 969 static RTEXITCODE SignToolPkcs7_PrependCounterSignature(PRTCRPKCS7SIGNERINFO pSignerInfo, 970 PCRTCRPKCS7SIGNERINFO pCounterSignerInfo, unsigned cVerbosity) 971 { 972 /* Make sure the UnauthenticatedAttributes member is there. */ 973 RTEXITCODE rcExit = SignToolPkcs7_EnsureUnauthenticatedAttributesPresent(pSignerInfo); 974 if (rcExit != RTEXITCODE_SUCCESS) 975 return rcExit; 976 977 /* Append an entry to UnauthenticatedAttributes. */ 978 uint32_t iPos; 979 int rc = RTCrPkcs7Attributes_InsertEx(&pSignerInfo->UnauthenticatedAttributes, 0 /*iPosition*/, NULL /*pToClone*/, 980 &g_RTAsn1DefaultAllocator, &iPos); 981 if (RT_FAILURE(rc)) 982 return RTMsgErrorExitFailure("RTCrPkcs7Attributes_Append failed: %Rrc", rc); 983 Assert(iPos < pSignerInfo->UnauthenticatedAttributes.cItems); Assert(iPos == 0); 984 PRTCRPKCS7ATTRIBUTE pAttr = pSignerInfo->UnauthenticatedAttributes.papItems[iPos]; 985 986 if (cVerbosity >= 2) 987 RTMsgInfo("Adding UnauthenticatedAttribute #%u...", iPos); 988 989 /* Create the attrib and its sub-set of counter signatures. */ 990 rc = RTAsn1ObjId_InitFromString(&pAttr->Type, RTCR_PKCS9_ID_COUNTER_SIGNATURE_OID, pAttr->Allocation.pAllocator); 991 if (RT_FAILURE(rc)) 992 return RTMsgErrorExitFailure("RTAsn1ObjId_InitFromString failed: %Rrc", rc); 993 994 /** @todo Generalize the Type + enmType DYN stuff and generate setters. */ 995 Assert(pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_NOT_PRESENT); 996 Assert(pAttr->uValues.pContentInfos == NULL); 997 pAttr->enmType = RTCRPKCS7ATTRIBUTETYPE_COUNTER_SIGNATURES; 998 rc = RTAsn1MemAllocZ(&pAttr->Allocation, (void **)&pAttr->uValues.pCounterSignatures, 999 sizeof(*pAttr->uValues.pCounterSignatures)); 1000 if (RT_FAILURE(rc)) 1001 return RTMsgErrorExitFailure("RTAsn1MemAllocZ failed: %Rrc", rc); 1002 1003 rc = RTCrPkcs7SignerInfos_Init(pAttr->uValues.pCounterSignatures, pAttr->Allocation.pAllocator); 1004 if (RT_FAILURE(rc)) 1005 return RTMsgErrorExitFailure("RTCrPkcs7SignerInfos_Init failed: %Rrc", rc); 1006 1007 /* Insert the counter signature. */ 1008 rc = RTCrPkcs7SignerInfos_InsertEx(pAttr->uValues.pCounterSignatures, 0 /*iPosition*/, pCounterSignerInfo, 1009 pAttr->Allocation.pAllocator, NULL); 1010 if (RT_FAILURE(rc)) 1011 return RTMsgErrorExitFailure("RTCrPkcs7SignerInfos_InsertEx failed: %Rrc", rc); 1012 1013 return RTEXITCODE_SUCCESS; 1014 } 1015 1016 1017 static RTEXITCODE SignToolPkcs7_AppendCertificate(PRTCRPKCS7SIGNEDDATA pSignedData, PCRTCRX509CERTIFICATE pCertToAppend) 1018 { 1019 if (pSignedData->Certificates.cItems == 0 && !RTCrPkcs7SetOfCerts_IsPresent(&pSignedData->Certificates)) 1020 return RTMsgErrorExitFailure("PKCS#7 signature includes no certificates! Didn't expect that"); 1021 1022 /* Already there? */ 1023 PCRTCRX509CERTIFICATE pExisting 1024 = RTCrPkcs7SetOfCerts_FindX509ByIssuerAndSerialNumber(&pSignedData->Certificates, &pCertToAppend->TbsCertificate.Issuer, 1025 &pCertToAppend->TbsCertificate.SerialNumber); 1026 if (!pExisting || RTCrX509Certificate_Compare(pExisting, pCertToAppend) != 0) 1027 { 1028 /* Append a RTCRPKCS7CERT entry. */ 1029 //int32_t iPos = RTCrPkcs7SetOfCerts_Append(&pSignedData->Certificates); 1030 //if (iPos < 0) 1031 // return RTMsgErrorExitFailure("RTCrPkcs7SetOfCerts_Append failed: %Rrc", iPos); 1032 uint32_t iPos; 1033 int rc = RTCrPkcs7SetOfCerts_InsertEx(&pSignedData->Certificates, 0 /*iPosition*/, NULL /*pToClone*/, 1034 &g_RTAsn1DefaultAllocator, &iPos); 1035 if (RT_FAILURE(rc)) 1036 return RTMsgErrorExitFailure("RTCrPkcs7SetOfCerts_Append failed: %Rrc", rc); 1037 1038 PRTCRPKCS7CERT pCertEntry = pSignedData->Certificates.papItems[iPos]; 1039 1040 /** @todo Generalize the Type + enmType DYN stuff and generate setters. */ 1041 Assert(pCertEntry->enmChoice == RTCRPKCS7CERTCHOICE_INVALID); 1042 Assert(pCertEntry->u.pX509Cert == NULL); 1043 pCertEntry->enmChoice = RTCRPKCS7CERTCHOICE_X509; 1044 rc = RTAsn1MemAllocZ(&pCertEntry->Allocation, (void **)&pCertEntry->u.pX509Cert, sizeof(*pCertEntry->u.pX509Cert)); 1045 if (RT_FAILURE(rc)) 1046 return RTMsgErrorExitFailure("RTAsn1MemAllocZ failed: %Rrc", rc); 1047 1048 /* Copy over the certificate we wish to append. */ 1049 rc = RTCrX509Certificate_Clone(pCertEntry->u.pX509Cert, pCertToAppend, pCertEntry->Allocation.pAllocator); 1050 if (RT_FAILURE(rc)) 1051 return RTMsgErrorExitFailure("RTCrX509Certificate_Clone failed: %Rrc", rc); 1052 } 1053 return RTEXITCODE_SUCCESS; 1054 } 1055 1056 1057 static RTEXITCODE Pkcs7SignStuff(const char *pszWhat, const void *pvToDataToSign, size_t cbToDataToSign, 1058 PCRTCRPKCS7ATTRIBUTES pAuthAttribs, RTCRSTORE hAdditionalCerts, uint32_t fExtraFlags, 1059 RTDIGESTTYPE enmDigestType, PCRTCRX509CERTIFICATE pTimestampCert, RTCRKEY hTimestampKey, 1060 unsigned cVerbosity, void **ppvSigned, size_t *pcbSigned, 1061 PRTCRPKCS7CONTENTINFO pContentInfo, PRTCRPKCS7SIGNEDDATA *ppSignedData) 1062 { 1063 *ppvSigned = NULL; 1064 if (pcbSigned) 1065 *pcbSigned = 0; 1066 if (ppSignedData) 1067 *ppSignedData = NULL; 1068 1069 /* Figure out how large the signature will be. */ 1070 RTERRINFOSTATIC ErrInfo; 1071 size_t cbSigned = 1024; 1072 int rc = RTCrPkcs7SimpleSignSignedData(RTCRPKCS7SIGN_SD_F_NO_SMIME_CAP | fExtraFlags, 1073 pTimestampCert, hTimestampKey, pvToDataToSign, cbToDataToSign, 1074 enmDigestType, hAdditionalCerts, pAuthAttribs, 1075 NULL, &cbSigned, RTErrInfoInitStatic(&ErrInfo)); 1076 if (rc != VERR_BUFFER_OVERFLOW) 1077 return RTMsgErrorExitFailure("RTCrPkcs7SimpleSignSignedData failed: %Rrc%#RTeim", rc, &ErrInfo.Core); 1078 1079 /* Allocate memory for it and do the actual signing. */ 1080 void *pvSigned = RTMemTmpAllocZ(cbSigned); 1081 if (!pvSigned) 1082 return RTMsgErrorExitFailure("Failed to allocate %#zx bytes for %s signature", cbSigned, pszWhat); 1083 rc = RTCrPkcs7SimpleSignSignedData(RTCRPKCS7SIGN_SD_F_NO_SMIME_CAP | fExtraFlags, 1084 pTimestampCert, hTimestampKey, pvToDataToSign, cbToDataToSign, 1085 enmDigestType, hAdditionalCerts, pAuthAttribs, 1086 pvSigned, &cbSigned, RTErrInfoInitStatic(&ErrInfo)); 1087 if (RT_SUCCESS(rc)) 1088 { 1089 if (cVerbosity > 2) 1090 RTMsgInfo("%s signature: %#zx bytes\n%.*Rhxd\n", pszWhat, cbSigned, cbSigned, pvSigned); 1091 1092 /* 1093 * Decode the signature and check that it is SignedData. 1094 */ 1095 RTASN1CURSORPRIMARY PrimaryCursor; 1096 RTAsn1CursorInitPrimary(&PrimaryCursor, pvSigned, (uint32_t)cbSigned, RTErrInfoInitStatic(&ErrInfo), 1097 &g_RTAsn1DefaultAllocator, 0, pszWhat); 1098 rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, pContentInfo, "CI"); 1099 if (RT_SUCCESS(rc)) 1100 { 1101 if (RTCrPkcs7ContentInfo_IsSignedData(pContentInfo)) 1102 { 1103 *ppvSigned = pvSigned; 1104 if (pcbSigned) 1105 *pcbSigned = cbSigned; 1106 if (ppSignedData) 1107 *ppSignedData = pContentInfo->u.pSignedData; 1108 1109 if (cVerbosity) 1110 { 1111 SHOWEXEPKCS7 ShowExe; 1112 RT_ZERO(ShowExe); 1113 ShowExe.cVerbosity = cVerbosity; 1114 HandleShowExeWorkerPkcs7Display(&ShowExe, pContentInfo->u.pSignedData, 0, pContentInfo); 1115 } 1116 return RTEXITCODE_SUCCESS; 1117 } 1118 1119 RTMsgError("RTCrPkcs7SimpleSignSignedData did not create SignedData: %s", pContentInfo->ContentType.szObjId); 1120 } 1121 else 1122 RTMsgError("RTCrPkcs7ContentInfo_DecodeAsn1 failed: %Rrc%#RTeim", rc, &ErrInfo.Core); 1123 RTCrPkcs7ContentInfo_Delete(pContentInfo); 1124 } 1125 RTMemTmpFree(pvSigned); 1126 return RTEXITCODE_FAILURE; 1127 } 1128 1129 1130 static RTEXITCODE SignToolPkcs7_AddTimestampSignature(SIGNTOOLPKCS7EXE *pThis, unsigned cVerbosity, unsigned iSignature, 1131 bool fReplaceExisting, bool fTimestampTypeOld, RTTIMESPEC SigningTime, 1132 PCRTCRX509CERTIFICATE pTimestampCert, RTCRKEY hTimestampKey) 1133 { 1134 AssertReturn(fTimestampTypeOld, RTMsgErrorExitFailure("New style signatures not supported yet")); 1135 1136 /* 1137 * Locate the signature specified by iSignature: 1138 */ 1139 PRTCRPKCS7SIGNEDDATA pSignedData = NULL; 1140 PRTCRPKCS7SIGNERINFO pSignerInfo = SignToolPkcs7_FindNestedSignatureByIndex(pThis, iSignature, &pSignedData); 1141 if (!pSignerInfo) 1142 return RTMsgErrorExitFailure("No signature #%u in %s", iSignature, pThis->pszFilename); 1143 1144 /* 1145 * Create a set of attributes we need to include in the AuthenticatedAttributes 1146 * of the timestamp signature. 1147 */ 1148 RTCRPKCS7ATTRIBUTES AuthAttribs; 1149 int rc = RTCrPkcs7Attributes_Init(&AuthAttribs, &g_RTAsn1DefaultAllocator); 1150 if (RT_FAILURE(rc)) 1151 return RTMsgErrorExitFailure("RTCrPkcs7SetOfAttributes_Init failed: %Rrc", rc); 1152 1153 RTEXITCODE rcExit = AddAuthAttribsForTimestamp(&AuthAttribs, fTimestampTypeOld, SigningTime, pTimestampCert); 1154 if (rcExit == RTEXITCODE_SUCCESS) 1155 { 1156 /* 1157 * Now create a PKCS#7 signature of the encrypted signature from the selected signer info. 1158 */ 1159 void *pvSigned = NULL; 1160 PRTCRPKCS7SIGNEDDATA pTsSignedData = NULL; 1161 RTCRPKCS7CONTENTINFO TsContentInfo; 1162 rcExit = Pkcs7SignStuff("timestamp", pSignerInfo->EncryptedDigest.Asn1Core.uData.pv, 1163 pSignerInfo->EncryptedDigest.Asn1Core.cb, &AuthAttribs, NIL_RTCRSTORE /*hAdditionalCerts*/, 1164 RTCRPKCS7SIGN_SD_F_DEATCHED, RTDIGESTTYPE_SHA1, pTimestampCert, hTimestampKey, cVerbosity, 1165 &pvSigned, NULL /*pcbSigned*/, &TsContentInfo, &pTsSignedData); 1166 if (rcExit == RTEXITCODE_SUCCESS) 1167 { 1168 1169 /* 1170 * If we're replacing existing timestamp signatures, remove old ones now. 1171 */ 1172 if ( fReplaceExisting 1173 && RTCrPkcs7Attributes_IsPresent(&pSignerInfo->UnauthenticatedAttributes)) 1174 { 1175 uint32_t iItem = pSignerInfo->UnauthenticatedAttributes.cItems; 1176 while (iItem-- > 0) 1177 { 1178 PRTCRPKCS7ATTRIBUTE pAttr = pSignerInfo->UnauthenticatedAttributes.papItems[iItem]; 1179 if (pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_COUNTER_SIGNATURES) /* ASSUMES all counter sigs are timstamps */ 1180 { 1181 if (cVerbosity > 1) 1182 RTMsgInfo("Removing counter signature in attribute #%u\n", iItem); 1183 rc = RTCrPkcs7Attributes_Erase(&pSignerInfo->UnauthenticatedAttributes, iItem); 1184 if (RT_FAILURE(rc)) 1185 rcExit = RTMsgErrorExitFailure("RTCrPkcs7Attributes_Erase failed on #%u: %Rrc", iItem, rc); 1186 } 1187 } 1188 } 1189 1190 /* 1191 * Add the new one. 1192 */ 1193 if (rcExit == RTEXITCODE_SUCCESS) 1194 rcExit = SignToolPkcs7_PrependCounterSignature(pSignerInfo, pTsSignedData->SignerInfos.papItems[0], cVerbosity); 1195 1196 /* 1197 * Make sure the signing certificate is included. 1198 */ 1199 if (rcExit == RTEXITCODE_SUCCESS) 1200 rcExit = SignToolPkcs7_AppendCertificate(pSignedData, pTimestampCert); 1201 1202 /* 1203 * Clean up. 1204 */ 1205 RTCrPkcs7ContentInfo_Delete(&TsContentInfo); 1206 RTMemTmpFree(pvSigned); 1207 } 1208 } 1209 RTCrPkcs7Attributes_Delete(&AuthAttribs); 1210 1211 RT_NOREF(cVerbosity, fReplaceExisting, fTimestampTypeOld); 1212 return rcExit; 1213 } 1214 1215 #endif /* !IPRT_IN_BUILD_TOOL */ 1216 1217 1218 /********************************************************************************************************************************* 1219 * The 'extract-exe-signer-cert' command. * 1220 *********************************************************************************************************************************/ 1221 889 1222 static RTEXITCODE HelpExtractExeSignerCert(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel) 890 1223 { 891 1224 RT_NOREF_PV(enmLevel); 892 RTStrmPrintf(pStrm, "extract-exe-signer-cert [--ber|--cer|--der] [--signature-index|-i <num>] [--exe|-e] <exe> [--output|-o] <outfile.cer>\n"); 1225 RTStrmWrappedPrintf(pStrm, RTSTRMWRAPPED_F_HANGING_INDENT, 1226 "extract-exe-signer-cert [--ber|--cer|--der] [--signature-index|-i <num>] [--exe|-e] <exe> [--output|-o] <outfile.cer>\n"); 893 1227 return RTEXITCODE_SUCCESS; 894 1228 } … … 1016 1350 1017 1351 1018 /* 1019 * The 'add-nested-exe-signature' command. 1020 */ 1352 /********************************************************************************************************************************* 1353 * The 'add-nested-exe-signature' command. * 1354 *********************************************************************************************************************************/ 1355 1021 1356 static RTEXITCODE HelpAddNestedExeSignature(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel) 1022 1357 { 1023 1358 RT_NOREF_PV(enmLevel); 1024 RTStrmPrintf(pStrm, "add-nested-exe-signature [-v|--verbose] [-d|--debug] [-p|--prepend] <destination-exe> <source-exe>\n"); 1359 RTStrmWrappedPrintf(pStrm, RTSTRMWRAPPED_F_HANGING_INDENT, 1360 "add-nested-exe-signature [-v|--verbose] [-d|--debug] [-p|--prepend] <destination-exe> <source-exe>\n"); 1025 1361 if (enmLevel == RTSIGNTOOLHELP_FULL) 1026 RTStrmPrintf(pStrm, 1027 "\n" 1028 "The --debug option allows the source-exe to be omitted in order to test the\n" 1029 "encoding and PE file modification.\n" 1030 "\n" 1031 "The --prepend option puts the nested signature first rather than appending it\n" 1032 "to the end of of the nested signature set. Windows reads nested signatures in\n" 1033 "reverse order, so --prepend will logically putting it last.\n" 1034 ); 1362 RTStrmWrappedPrintf(pStrm, 0, 1363 "\n" 1364 "The --debug option allows the source-exe to be omitted in order to test the " 1365 "encoding and PE file modification.\n" 1366 "\n" 1367 "The --prepend option puts the nested signature first rather than appending it " 1368 "to the end of of the nested signature set. Windows reads nested signatures in " 1369 "reverse order, so --prepend will logically putting it last.\n"); 1035 1370 return RTEXITCODE_SUCCESS; 1036 1371 } … … 1124 1459 1125 1460 1126 /* 1127 * The 'add-nested-cat-signature' command. 1128 */ 1461 /********************************************************************************************************************************* 1462 * The 'add-nested-cat-signature' command. * 1463 *********************************************************************************************************************************/ 1464 1129 1465 static RTEXITCODE HelpAddNestedCatSignature(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel) 1130 1466 { 1131 1467 RT_NOREF_PV(enmLevel); 1132 RTStrmPrintf(pStrm, "add-nested-cat-signature [-v|--verbose] [-d|--debug] [-p|--prepend] <destination-cat> <source-cat>\n"); 1468 RTStrmWrappedPrintf(pStrm, RTSTRMWRAPPED_F_HANGING_INDENT, 1469 "add-nested-cat-signature [-v|--verbose] [-d|--debug] [-p|--prepend] <destination-cat> <source-cat>\n"); 1133 1470 if (enmLevel == RTSIGNTOOLHELP_FULL) 1134 RTStrmPrintf(pStrm, 1135 "\n" 1136 "The --debug option allows the source-cat to be omitted in order to test the\n" 1137 "ASN.1 re-encoding of the destination catalog file.\n" 1138 "\n" 1139 "The --prepend option puts the nested signature first rather than appending it\n" 1140 "to the end of of the nested signature set. Windows reads nested signatures in\n" 1141 "reverse order, so --prepend will logically putting it last.\n" 1142 ); 1471 RTStrmWrappedPrintf(pStrm, 0, 1472 "\n" 1473 "The --debug option allows the source-cat to be omitted in order to test the " 1474 "ASN.1 re-encoding of the destination catalog file.\n" 1475 "\n" 1476 "The --prepend option puts the nested signature first rather than appending it " 1477 "to the end of of the nested signature set. Windows reads nested signatures in " 1478 "reverse order, so --prepend will logically putting it last.\n"); 1143 1479 return RTEXITCODE_SUCCESS; 1144 1480 } … … 1233 1569 #ifndef IPRT_IN_BUILD_TOOL 1234 1570 1571 /********************************************************************************************************************************* 1572 * The 'add-timestamp-exe-signature' command. * 1573 *********************************************************************************************************************************/ 1574 1575 static RTEXITCODE HelpAddTimestampExeSignature(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel) 1576 { 1577 RT_NOREF_PV(enmLevel); 1578 1579 RTStrmWrappedPrintf(pStrm, RTSTRMWRAPPED_F_HANGING_INDENT, 1580 "add-timestamp-exe-signature [-v|--verbose] [--signature-index|-i <num>] " 1581 "[--timestamp-cert-file <file>] " 1582 "[--timestamp-type old|new] " 1583 "[--timestamp-date <fake-isots>] " 1584 "[--timestamp-year <fake-year>] " 1585 "[--replace-existing|-r] " 1586 "<exe>\n"); 1587 if (enmLevel == RTSIGNTOOLHELP_FULL) 1588 RTStrmWrappedPrintf(pStrm, 0, 1589 "This is mainly to test timestamp code.\n" 1590 "\n" 1591 "The --timestamp-date option takes an ISO timestamp, but will replace the time part with the " 1592 "current time.\n" 1593 "\n"); 1594 return RTEXITCODE_SUCCESS; 1595 } 1596 1597 1598 static RTEXITCODE HandleAddTimestampExeSignature(int cArgs, char **papszArgs) 1599 { 1600 RTERRINFOSTATIC ErrInfo; 1601 1602 /* 1603 * Parse arguments. 1604 */ 1605 static const RTGETOPTDEF s_aOptions[] = 1606 { 1607 { "--signature-index", 'i', RTGETOPT_REQ_UINT32 }, 1608 { "--timestamp-cert-file", OPT_TIMESTAMP_CERT_FILE, RTGETOPT_REQ_STRING }, 1609 { "--timestamp-key-file", OPT_TIMESTAMP_KEY_FILE, RTGETOPT_REQ_STRING }, 1610 { "--timestamp-type", OPT_TIMESTAMP_TYPE, RTGETOPT_REQ_STRING }, 1611 { "--timestamp-date", OPT_TIMESTAMP_DATE, RTGETOPT_REQ_STRING }, 1612 { "--timestamp-year", OPT_TIMESTAMP_YEAR, RTGETOPT_REQ_UINT32 }, 1613 { "--replace-existing", 'r', RTGETOPT_REQ_NOTHING }, 1614 { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, 1615 }; 1616 1617 unsigned cVerbosity = 0; 1618 unsigned iSignature = 0; 1619 bool fReplaceExisting = false; 1620 bool fTimestampTypeOld = true; 1621 RTCRX509CERTIFICATE TimestampCertificate; /* leaked */ 1622 PCRTCRX509CERTIFICATE pTimestampCertificate = NULL; 1623 RTCRKEY hTimestampPrivateKey = NIL_RTCRKEY; 1624 RTTIMESPEC SigningTime; 1625 RTTimeNow(&SigningTime); 1626 1627 RTGETOPTSTATE GetState; 1628 int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); 1629 AssertRCReturn(rc, RTEXITCODE_FAILURE); 1630 1631 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 1632 RTGETOPTUNION ValueUnion; 1633 int ch; 1634 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 1635 { 1636 switch (ch) 1637 { 1638 case 'i': 1639 iSignature = ValueUnion.u32; 1640 break; 1641 1642 case OPT_TIMESTAMP_CERT_FILE: 1643 { 1644 if (pTimestampCertificate == &TimestampCertificate) 1645 RTCrX509Certificate_Delete(&TimestampCertificate); 1646 rc = RTCrX509Certificate_ReadFromFile(&TimestampCertificate, ValueUnion.psz, 0, &g_RTAsn1DefaultAllocator, 1647 RTErrInfoInitStatic(&ErrInfo)); 1648 if (RT_FAILURE(rc)) 1649 return RTMsgErrorExitFailure("Error reading certificate from '%s': %Rrc%#RTeim", 1650 ValueUnion.psz, rc, &ErrInfo.Core); 1651 pTimestampCertificate = &TimestampCertificate; 1652 break; 1653 } 1654 1655 case OPT_TIMESTAMP_KEY_FILE: 1656 RTCrKeyRelease(hTimestampPrivateKey); 1657 rc = RTCrKeyCreateFromFile(&hTimestampPrivateKey, 0 /*fFlags*/, ValueUnion.psz, 1658 NULL /*pszPassword*/, RTErrInfoInitStatic(&ErrInfo)); 1659 if (RT_FAILURE(rc)) 1660 return RTMsgErrorExitFailure("Error reading private key from '%s': %Rrc%#RTeim", 1661 ValueUnion.psz, rc, &ErrInfo.Core); 1662 break; 1663 1664 case OPT_TIMESTAMP_TYPE: 1665 if (strcmp(ValueUnion.psz, "old") == 0) 1666 fTimestampTypeOld = true; 1667 else if (strcmp(ValueUnion.psz, "new") == 0) 1668 fTimestampTypeOld = false; 1669 else 1670 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown timestamp type: %s", ValueUnion.psz); 1671 break; 1672 1673 case OPT_TIMESTAMP_DATE: 1674 { 1675 RTTIMESPEC Tmp; 1676 if (RTTimeSpecFromString(&Tmp, ValueUnion.psz)) 1677 { 1678 RTTIME Time, Now; 1679 RTTimeExplode(&Time, &Tmp); 1680 RTTimeExplode(&Now, RTTimeNow(&Tmp)); 1681 Time.u8Hour = Now.u8Hour; 1682 Time.u8Minute = Now.u8Minute; 1683 Time.u8Second = Now.u8Second; 1684 Time.u32Nanosecond = Now.u32Nanosecond; 1685 RTTimeImplode(&SigningTime, &Time); 1686 } 1687 else 1688 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid timestamp: %s", ValueUnion.psz); 1689 break; 1690 } 1691 1692 case OPT_TIMESTAMP_YEAR: 1693 { 1694 if (ValueUnion.u32 <= 1950 || ValueUnion.u32 >= 2050) 1695 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid timestamp year: %u, valid range 1951-2049", ValueUnion.u32); 1696 1697 RTTIME Time; 1698 RTTimeExplode(&Time, RTTimeNow(&SigningTime)); 1699 Time.i32Year = (int32_t)ValueUnion.u32; 1700 if (Time.u8MonthDay == 29 && Time.u8Month == 2 && !RTTimeIsLeapYear(Time.i32Year)) 1701 Time.u8MonthDay = 28; 1702 RTTimeImplode(&SigningTime, &Time); 1703 break; 1704 } 1705 1706 case 'r': 1707 fReplaceExisting = true; 1708 break; 1709 1710 case 'v': 1711 cVerbosity++; 1712 break; 1713 1714 case 'V': 1715 return HandleVersion(cArgs, papszArgs); 1716 1717 case 'h': 1718 return HelpAddTimestampExeSignature(g_pStdOut, RTSIGNTOOLHELP_FULL); 1719 1720 case VINF_GETOPT_NOT_OPTION: 1721 { 1722 /* check that we've got all the info we need: */ 1723 if (!pTimestampCertificate) 1724 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No timestamp certificate was specified"); 1725 if (hTimestampPrivateKey == NIL_RTCRKEY) 1726 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No timestamp private key was specified"); 1727 1728 /* Do the work: */ 1729 SIGNTOOLPKCS7EXE Exe; 1730 RTEXITCODE rcExit2 = SignToolPkcs7Exe_InitFromFile(&Exe, ValueUnion.psz, cVerbosity); 1731 if (rcExit2 == RTEXITCODE_SUCCESS) 1732 { 1733 rcExit2 = SignToolPkcs7_AddTimestampSignature(&Exe, cVerbosity, iSignature, fReplaceExisting, 1734 fTimestampTypeOld, SigningTime, 1735 pTimestampCertificate, hTimestampPrivateKey); 1736 if (rcExit2 == RTEXITCODE_SUCCESS) 1737 rcExit2 = SignToolPkcs7_Encode(&Exe, cVerbosity); 1738 if (rcExit2 == RTEXITCODE_SUCCESS) 1739 rcExit2 = SignToolPkcs7Exe_WriteSignatureToFile(&Exe, cVerbosity); 1740 SignToolPkcs7Exe_Delete(&Exe); 1741 } 1742 if (rcExit2 != RTEXITCODE_SUCCESS && rcExit == RTEXITCODE_SUCCESS) 1743 rcExit = rcExit2; 1744 break; 1745 } 1746 1747 default: 1748 return RTGetOptPrintError(ch, &ValueUnion); 1749 } 1750 } 1751 return rcExit; 1752 } 1753 1754 #endif /*!IPRT_IN_BUILD_TOOL */ 1755 #ifndef IPRT_IN_BUILD_TOOL 1756 1235 1757 /* 1236 1758 * The 'verify-exe' command. … … 1239 1761 { 1240 1762 RT_NOREF_PV(enmLevel); 1241 RTStrm Printf(pStrm,1242 "verify-exe [--verbose|--quiet] [--kernel] [--root <root-cert.der>] [--additional <supp-cert.der>]\n"1243 "[--type <win|osx>] <exe1> [exe2 [..]]\n");1763 RTStrmWrappedPrintf(pStrm, RTSTRMWRAPPED_F_HANGING_INDENT, 1764 "verify-exe [--verbose|--quiet] [--kernel] [--root <root-cert.der>] [--additional <supp-cert.der>] " 1765 "[--type <win|osx>] <exe1> [exe2 [..]]\n"); 1244 1766 return RTEXITCODE_SUCCESS; 1245 1767 } … … 2350 2872 { 2351 2873 RT_NOREF_PV(enmLevel); 2352 RTStrmPrintf(pStrm, 2353 "show-exe [--verbose|-v] [--quiet|-q] <exe1> [exe2 [..]]\n"); 2874 RTStrmWrappedPrintf(pStrm, RTSTRMWRAPPED_F_HANGING_INDENT, "show-exe [--verbose|-v] [--quiet|-q] <exe1> [exe2 [..]]\n"); 2354 2875 return RTEXITCODE_SUCCESS; 2355 2876 } … … 2428 2949 { 2429 2950 RT_NOREF_PV(enmLevel); 2430 RTStrmPrintf(pStrm, 2431 "show-cat [--verbose|-v] [--quiet|-q] <cat1> [cat2 [..]]\n"); 2951 RTStrmWrappedPrintf(pStrm, RTSTRMWRAPPED_F_HANGING_INDENT, "show-cat [--verbose|-v] [--quiet|-q] <cat1> [cat2 [..]]\n"); 2432 2952 return RTEXITCODE_SUCCESS; 2433 2953 } … … 2507 3027 { 2508 3028 RT_NOREF_PV(enmLevel); 2509 RTStrm Printf(pStrm,2510 "make-tainfo [--verbose|--quiet] [--cert <cert.der>] [-o|--output] <tainfo.der>\n");3029 RTStrmWrappedPrintf(pStrm, RTSTRMWRAPPED_F_HANGING_INDENT, 3030 "make-tainfo [--verbose|--quiet] [--cert <cert.der>] [-o|--output] <tainfo.der>\n"); 2511 3031 return RTEXITCODE_SUCCESS; 2512 3032 } … … 2764 3284 { "add-nested-cat-signature", HandleAddNestedCatSignature, HelpAddNestedCatSignature }, 2765 3285 #ifndef IPRT_IN_BUILD_TOOL 3286 { "add-timestamp-exe-signature", HandleAddTimestampExeSignature, HelpAddTimestampExeSignature }, 3287 #endif 3288 #ifndef IPRT_IN_BUILD_TOOL 2766 3289 { "verify-exe", HandleVerifyExe, HelpVerifyExe }, 2767 3290 #endif … … 2792 3315 RTSIGNTOOLHELP enmLevel = cArgs <= 1 ? RTSIGNTOOLHELP_USAGE : RTSIGNTOOLHELP_FULL; 2793 3316 uint32_t cShowed = 0; 3317 uint32_t cchWidth; 3318 if (RT_FAILURE(RTStrmQueryTerminalWidth(g_pStdOut, &cchWidth))) 3319 cchWidth = 80; 2794 3320 for (uint32_t iCmd = 0; iCmd < RT_ELEMENTS(g_aCommands); iCmd++) 2795 3321 { … … 2800 3326 fShow = true; 2801 3327 else 2802 {2803 3328 for (int iArg = 1; iArg < cArgs; iArg++) 2804 3329 if (RTStrSimplePatternMultiMatch(papszArgs[iArg], RTSTR_MAX, g_aCommands[iCmd].pszCmd, RTSTR_MAX, NULL)) … … 2807 3332 break; 2808 3333 } 2809 }2810 3334 if (fShow) 2811 3335 { 3336 if (cShowed && enmLevel == RTSIGNTOOLHELP_FULL) 3337 RTPrintf("%.*s\n", RT_MIN(cchWidth, 100), 3338 "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "); 2812 3339 g_aCommands[iCmd].pfnHelp(g_pStdOut, enmLevel); 2813 3340 cShowed++;
Note:
See TracChangeset
for help on using the changeset viewer.