VirtualBox

Ignore:
Timestamp:
Jul 16, 2022 11:52:40 PM (2 years ago)
Author:
vboxsync
Message:

RTSignTool: Merged sign-exe and sign-cat into a single command, detecting the file type by reading the start of the file. bugref:8691

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/tools/RTSignTool.cpp

    r95674 r95675  
    4242#include <iprt/stream.h>
    4343#include <iprt/string.h>
     44#ifdef RT_OS_WINDOWS
     45# include <iprt/utf16.h>
     46#endif
    4447#include <iprt/uuid.h>
    4548#include <iprt/zero.h>
     49#include <iprt/formats/asn1.h>
     50#include <iprt/formats/mach-o.h>
    4651#ifndef RT_OS_WINDOWS
    4752# include <iprt/formats/pecoff.h>
    48 #else
    49 # include <iprt/utf16.h>
    5053#endif
    5154#include <iprt/crypto/applecodesign.h>
     
    6770# include <ncrypt.h>
    6871#endif
     72#include "internal/ldr.h" /* for IMAGE_XX_SIGNATURE defines */
    6973
    7074
     
    137141#define OPT_TIMESTAMP_OVERRIDE              1044
    138142#define OPT_NO_SIGNING_TIME                 1045
     143#define OPT_FILE_TYPE                       1046
    139144
    140145
     
    148153    RTSIGNTOOLHELP_FULL
    149154} RTSIGNTOOLHELP;
     155
     156
     157/** Filetypes. */
     158typedef enum RTSIGNTOOLFILETYPE
     159{
     160    RTSIGNTOOLFILETYPE_INVALID = 0,
     161    RTSIGNTOOLFILETYPE_DETECT,
     162    RTSIGNTOOLFILETYPE_EXE,
     163    RTSIGNTOOLFILETYPE_CAT,
     164    RTSIGNTOOLFILETYPE_UNKNOWN,
     165    RTSIGNTOOLFILETYPE_END
     166} RTSIGNTOOLFILETYPE;
    150167
    151168
     
    31873204}
    31883205
     3206static RTEXITCODE HandleOptFileType(RTSIGNTOOLFILETYPE *penmFileType, const char *pszType)
     3207{
     3208    if (strcmp(pszType, "detect") == 0 || strcmp(pszType, "auto") == 0)
     3209        *penmFileType = RTSIGNTOOLFILETYPE_DETECT;
     3210    else if (strcmp(pszType, "exe") == 0)
     3211        *penmFileType = RTSIGNTOOLFILETYPE_EXE;
     3212    else if (strcmp(pszType, "cat") == 0)
     3213        *penmFileType = RTSIGNTOOLFILETYPE_CAT;
     3214    else
     3215        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown forced file type: %s", pszType);
     3216    return RTEXITCODE_SUCCESS;
     3217}
     3218
     3219/**
     3220 * Detects the type of files @a pszFile is (by reading from it).
     3221 *
     3222 * @returns The file type, or RTSIGNTOOLFILETYPE_UNKNOWN (error displayed).
     3223 * @param   enmForceFileType    Usually set to RTSIGNTOOLFILETYPE_DETECT, but if
     3224 *                              not we'll return this without probing the file.
     3225 * @param   pszFile             The name of the file to detect the type of.
     3226 */
     3227static RTSIGNTOOLFILETYPE DetectFileType(RTSIGNTOOLFILETYPE enmForceFileType, const char *pszFile)
     3228{
     3229    /*
     3230     * Forced?
     3231     */
     3232    if (enmForceFileType != RTSIGNTOOLFILETYPE_DETECT)
     3233        return enmForceFileType;
     3234
     3235    /*
     3236     * Read the start of the file.
     3237     */
     3238    RTFILE hFile = NIL_RTFILE;
     3239    int rc = RTFileOpen(&hFile, pszFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
     3240    if (RT_FAILURE(rc))
     3241    {
     3242        RTMsgError("Error opening '%s' for reading: %Rrc", pszFile, rc);
     3243        return RTSIGNTOOLFILETYPE_UNKNOWN;
     3244    }
     3245
     3246    union
     3247    {
     3248        uint8_t     ab[256];
     3249        uint16_t    au16[256/2];
     3250        uint32_t    au32[256/4];
     3251    } uBuf;
     3252    RT_ZERO(uBuf);
     3253
     3254    size_t cbRead = 0;
     3255    rc = RTFileRead(hFile, &uBuf, sizeof(uBuf), &cbRead);
     3256    if (RT_FAILURE(rc))
     3257        RTMsgError("Error reading from '%s': %Rrc", pszFile, rc);
     3258
     3259    uint64_t cbFile;
     3260    int rcSize = RTFileQuerySize(hFile, &cbFile);
     3261    if (RT_FAILURE(rcSize))
     3262        RTMsgError("Error querying size of '%s': %Rrc", pszFile, rc);
     3263
     3264    RTFileClose(hFile);
     3265    if (RT_FAILURE(rc) || RT_FAILURE(rcSize))
     3266        return RTSIGNTOOLFILETYPE_UNKNOWN;
     3267
     3268    /*
     3269     * Try guess the kind of file.
     3270     */
     3271    /* All the executable magics we know: */
     3272    if (   uBuf.au16[0] == RT_H2LE_U16_C(IMAGE_DOS_SIGNATURE)
     3273        || uBuf.au16[0] == RT_H2LE_U16_C(IMAGE_NE_SIGNATURE)
     3274        || uBuf.au16[0] == RT_H2LE_U16_C(IMAGE_LX_SIGNATURE)
     3275        || uBuf.au16[0] == RT_H2LE_U16_C(IMAGE_LE_SIGNATURE)
     3276        || uBuf.au32[0] == RT_H2LE_U32_C(IMAGE_NT_SIGNATURE)
     3277        || uBuf.au32[0] == RT_H2LE_U32_C(IMAGE_ELF_SIGNATURE)
     3278        || uBuf.au32[0] == IMAGE_FAT_SIGNATURE
     3279        || uBuf.au32[0] == IMAGE_FAT_SIGNATURE_OE
     3280        || uBuf.au32[0] == IMAGE_MACHO32_SIGNATURE
     3281        || uBuf.au32[0] == IMAGE_MACHO32_SIGNATURE_OE
     3282        || uBuf.au32[0] == IMAGE_MACHO64_SIGNATURE
     3283        || uBuf.au32[0] == IMAGE_MACHO64_SIGNATURE_OE)
     3284        return RTSIGNTOOLFILETYPE_EXE;
     3285
     3286    /*
     3287     * Catalog files are PKCS#7 SignedData and starts with a ContentInfo, i.e.:
     3288     *  SEQUENCE {
     3289     *      contentType OBJECT IDENTIFIER,
     3290     *      content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
     3291     *  }
     3292     *
     3293     * We ASSUME that it's DER encoded and doesn't use an indefinite length form
     3294     * at the start and that contentType is signedData (1.2.840.113549.1.7.2).
     3295     *
     3296     * Example of a 10353 (0x2871) byte long file:
     3297     *                       vv-------- contentType -------vv
     3298     * 00000000  30 82 28 6D 06 09 2A 86 48 86 F7 0D 01 07 02 A0
     3299     * 00000010  82 28 5E 30 82 28 5A 02 01 01 31 0B 30 09 06 05
     3300     */
     3301    if (   uBuf.ab[0] == (ASN1_TAG_SEQUENCE | ASN1_TAGFLAG_CONSTRUCTED)
     3302        && uBuf.ab[1] != 0x80 /* not indefinite form */
     3303        && uBuf.ab[1] >  0x30)
     3304    {
     3305        size_t   off   = 1;
     3306        uint32_t cbRec = uBuf.ab[1];
     3307        if (cbRec & 0x80)
     3308        {
     3309            cbRec &= 0x7f;
     3310            off   += cbRec;
     3311            switch (cbRec)
     3312            {
     3313                case 1: cbRec =                     uBuf.ab[2]; break;
     3314                case 2: cbRec = RT_MAKE_U16(        uBuf.ab[3], uBuf.ab[2]); break;
     3315                case 3: cbRec = RT_MAKE_U32_FROM_U8(uBuf.ab[4], uBuf.ab[3], uBuf.ab[2], 0); break;
     3316                case 4: cbRec = RT_MAKE_U32_FROM_U8(uBuf.ab[5], uBuf.ab[4], uBuf.ab[3], uBuf.ab[2]); break;
     3317                default: cbRec = UINT32_MAX; break;
     3318            }
     3319        }
     3320        if (off <= 5)
     3321        {
     3322            off++;
     3323            if (off + cbRec == cbFile)
     3324            {
     3325                /* If the contentType is signedData we're going to treat it as a catalog file,
     3326                   we don't currently much care about the signed content of a cat file. */
     3327                static const uint8_t s_abSignedDataOid[] =
     3328                { ASN1_TAG_OID, 9 /*length*/, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02 };
     3329                if (memcmp(&uBuf.ab[off], s_abSignedDataOid, sizeof(s_abSignedDataOid)) == 0)
     3330                    return RTSIGNTOOLFILETYPE_CAT;
     3331            }
     3332        }
     3333    }
     3334
     3335    RTMsgError("Unable to detect type of '%s'", pszFile);
     3336    return RTSIGNTOOLFILETYPE_UNKNOWN;
     3337}
     3338
    31893339#endif /* !IPRT_IN_BUILD_TOOL */
    31903340
     
    33063456#ifndef IPRT_IN_BUILD_TOOL
    33073457
    3308 static RTEXITCODE HelpSignExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
     3458static RTEXITCODE HelpSign(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
    33093459{
    33103460    RT_NOREF_PV(enmLevel);
     
    33343484
    33353485
    3336 static RTEXITCODE HandleSignExe(int cArgs, char **papszArgs)
     3486static RTEXITCODE HandleSign(int cArgs, char **papszArgs)
    33373487{
    33383488    /*
     
    33573507        { "--timestamp-type",       OPT_TIMESTAMP_TYPE,         RTGETOPT_REQ_STRING },
    33583508        { "--timestamp-override",   OPT_TIMESTAMP_OVERRIDE,     RTGETOPT_REQ_STRING },
     3509        { "--file-type",            OPT_FILE_TYPE,              RTGETOPT_REQ_STRING },
    33593510        { "--verbose",              'v',                        RTGETOPT_REQ_NOTHING },
    33603511        { "/v",                     'v',                        RTGETOPT_REQ_NOTHING },
     
    33673518    bool                    fHashPages              = false;
    33683519    bool                    fNoSigningTime          = false;
     3520    RTSIGNTOOLFILETYPE      enmForceFileType        = RTSIGNTOOLFILETYPE_DETECT;
    33693521    SignToolKeyPair         SigningCertKey("signing", true);
    33703522    RTCRSTORE               hAddCerts               = NIL_RTCRSTORE; /* leaked if returning directly (--help, --version) */
     
    33963548            case OPT_TIMESTAMP_TYPE:        rcExit2 = HandleOptTimestampType(&fTimestampTypeOld, ValueUnion.psz); break;
    33973549            case OPT_TIMESTAMP_OVERRIDE:    rcExit2 = HandleOptTimestampOverride(&SigningTime, ValueUnion.psz); break;
     3550            case OPT_FILE_TYPE:             rcExit2 = HandleOptFileType(&enmForceFileType, ValueUnion.psz); break;
    33983551            case 'v':                       cVerbosity++; break;
    33993552            case 'V':                       return HandleVersion(cArgs, papszArgs);
    3400             case 'h':                       return HelpSignExe(g_pStdOut, RTSIGNTOOLHELP_FULL);
     3553            case 'h':                       return HelpSign(g_pStdOut, RTSIGNTOOLHELP_FULL);
    34013554
    34023555            case VINF_GETOPT_NOT_OPTION:
    3403                 /* Do final certificate and key option processing (first file only). */
     3556                /*
     3557                 * Do final certificate and key option processing (first file only).
     3558                 */
    34043559                rcExit2 = SigningCertKey.finalizeOptions(cVerbosity);
    34053560                if (rcExit2 == RTEXITCODE_SUCCESS)
     
    34073562                if (rcExit2 == RTEXITCODE_SUCCESS)
    34083563                {
    3409                     /* Do the work: */
    3410                     SIGNTOOLPKCS7EXE Exe;
    3411                     rcExit2 = SignToolPkcs7Exe_InitFromFile(&Exe, ValueUnion.psz, cVerbosity,
    3412                                                             RTLDRARCH_WHATEVER, true /*fAllowUnsigned*/);
    3413                     if (rcExit2 == RTEXITCODE_SUCCESS)
     3564                    /*
     3565                     * Detect file type.
     3566                     */
     3567                    RTSIGNTOOLFILETYPE enmFileType = DetectFileType(enmForceFileType, ValueUnion.psz);
     3568                    if (enmFileType == RTSIGNTOOLFILETYPE_EXE)
    34143569                    {
    3415                         rcExit2 = SignToolPkcs7_AddOrReplaceSignature(&Exe, cVerbosity, enmSigType, fReplaceExisting, fHashPages,
    3416                                                                       fNoSigningTime, &SigningCertKey, hAddCerts,
    3417                                                                       fTimestampTypeOld, SigningTime, &TimestampCertKey);
     3570                        /*
     3571                         * Sign executable image.
     3572                         */
     3573                        SIGNTOOLPKCS7EXE Exe;
     3574                        rcExit2 = SignToolPkcs7Exe_InitFromFile(&Exe, ValueUnion.psz, cVerbosity,
     3575                                                                RTLDRARCH_WHATEVER, true /*fAllowUnsigned*/);
    34183576                        if (rcExit2 == RTEXITCODE_SUCCESS)
    3419                             rcExit2 = SignToolPkcs7_Encode(&Exe, cVerbosity);
     3577                        {
     3578                            rcExit2 = SignToolPkcs7_AddOrReplaceSignature(&Exe, cVerbosity, enmSigType, fReplaceExisting,
     3579                                                                          fHashPages, fNoSigningTime, &SigningCertKey, hAddCerts,
     3580                                                                          fTimestampTypeOld, SigningTime, &TimestampCertKey);
     3581                            if (rcExit2 == RTEXITCODE_SUCCESS)
     3582                                rcExit2 = SignToolPkcs7_Encode(&Exe, cVerbosity);
     3583                            if (rcExit2 == RTEXITCODE_SUCCESS)
     3584                                rcExit2 = SignToolPkcs7Exe_WriteSignatureToFile(&Exe, cVerbosity);
     3585                            SignToolPkcs7Exe_Delete(&Exe);
     3586                        }
     3587                    }
     3588                    else if (enmFileType == RTSIGNTOOLFILETYPE_CAT)
     3589                    {
     3590                        /*
     3591                         * Sign catalog file.
     3592                         */
     3593                        SIGNTOOLPKCS7 Cat;
     3594                        rcExit2 = SignToolPkcs7_InitFromFile(&Cat, ValueUnion.psz, cVerbosity);
    34203595                        if (rcExit2 == RTEXITCODE_SUCCESS)
    3421                             rcExit2 = SignToolPkcs7Exe_WriteSignatureToFile(&Exe, cVerbosity);
    3422                         SignToolPkcs7Exe_Delete(&Exe);
     3596                        {
     3597                            rcExit2 = SignToolPkcs7_AddOrReplaceCatSignature(&Cat, cVerbosity, enmSigType, fReplaceExisting,
     3598                                                                             fNoSigningTime, &SigningCertKey, hAddCerts,
     3599                                                                             fTimestampTypeOld, SigningTime, &TimestampCertKey);
     3600                            if (rcExit2 == RTEXITCODE_SUCCESS)
     3601                                rcExit2 = SignToolPkcs7_Encode(&Cat, cVerbosity);
     3602                            if (rcExit2 == RTEXITCODE_SUCCESS)
     3603                                rcExit2 = SignToolPkcs7_WriteSignatureToFile(&Cat, ValueUnion.psz, cVerbosity);
     3604                            SignToolPkcs7_Delete(&Cat);
     3605                        }
    34233606                    }
    3424                     if (rcExit2 != RTEXITCODE_SUCCESS && rcExit == RTEXITCODE_SUCCESS)
    3425                         rcExit = rcExit2;
    3426                     rcExit2 = RTEXITCODE_SUCCESS;
    3427                 }
    3428                 break;
    3429 
    3430             default:
    3431                 return RTGetOptPrintError(ch, &ValueUnion);
    3432         }
    3433         if (rcExit2 != RTEXITCODE_SUCCESS)
    3434         {
    3435             rcExit = rcExit2;
    3436             break;
    3437         }
    3438     }
    3439 
    3440     if (hAddCerts != NIL_RTCRSTORE)
    3441         RTCrStoreRelease(hAddCerts);
    3442     return rcExit;
    3443 }
    3444 
    3445 #endif /*!IPRT_IN_BUILD_TOOL */
    3446 
    3447 
    3448 /*********************************************************************************************************************************
    3449 *   The 'sign-cat' command.                                                                                   *
    3450 *********************************************************************************************************************************/
    3451 #ifndef IPRT_IN_BUILD_TOOL
    3452 
    3453 static RTEXITCODE HelpSignCat(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
    3454 {
    3455     RT_NOREF_PV(enmLevel);
    3456 
    3457     RTStrmWrappedPrintf(pStrm, RTSTRMWRAPPED_F_HANGING_INDENT,
    3458                         "sign-cat [-v|--verbose] "
    3459                         "[--type sha1|sha256] "
    3460                         "[--append] "
    3461                         OPT_CERT_KEY_SYNOPSIS("--")
    3462                         "[--add-cert <file>] "
    3463                         OPT_CERT_KEY_SYNOPSIS("--timestamp-")
    3464                         "[--timestamp-type old|new] "
    3465                         "[--timestamp-date <fake-isots>] "
    3466                         "[--timestamp-year <fake-year>] "
    3467                         "[--replace-existing|-r] "
    3468                         "<exe>\n");
    3469     if (enmLevel == RTSIGNTOOLHELP_FULL)
    3470         RTStrmWrappedPrintf(pStrm, 0,
    3471                             "Sign a catalog file.\n"
    3472                             "\n"
    3473                             "The --timestamp-override option can take a partial or full ISO timestamp.  It is merged "
    3474                             "with the current time if partial.\n"
    3475                             "\n");
    3476     return RTEXITCODE_SUCCESS;
    3477 }
    3478 
    3479 
    3480 static RTEXITCODE HandleSignCat(int cArgs, char **papszArgs)
    3481 {
    3482     /*
    3483      * Parse arguments.
    3484      */
    3485     static const RTGETOPTDEF s_aOptions[] =
    3486     {
    3487         { "--append",               'a',                        RTGETOPT_REQ_NOTHING },
    3488         { "/as",                    'a',                        RTGETOPT_REQ_NOTHING },
    3489         { "--type",                 't',                        RTGETOPT_REQ_STRING },
    3490         { "/fd",                    't',                        RTGETOPT_REQ_STRING },
    3491         { "--add-cert",             OPT_ADD_CERT,               RTGETOPT_REQ_STRING },
    3492         { "/ac",                    OPT_ADD_CERT,               RTGETOPT_REQ_STRING },
    3493         { "--no-signing-time",      OPT_NO_SIGNING_TIME,        RTGETOPT_REQ_NOTHING },
    3494         OPT_CERT_KEY_GETOPTDEF_ENTRIES("--",           1000),
    3495         OPT_CERT_KEY_GETOPTDEF_COMPAT_ENTRIES(         1000),
    3496         OPT_CERT_KEY_GETOPTDEF_ENTRIES("--timestamp-", 1020),
    3497         { "--timestamp-type",       OPT_TIMESTAMP_TYPE,         RTGETOPT_REQ_STRING },
    3498         { "--timestamp-override",   OPT_TIMESTAMP_OVERRIDE,     RTGETOPT_REQ_STRING },
    3499         { "--verbose",              'v',                        RTGETOPT_REQ_NOTHING },
    3500         { "/v",                     'v',                        RTGETOPT_REQ_NOTHING },
    3501         { "/debug",                 'v',                        RTGETOPT_REQ_NOTHING },
    3502     };
    3503 
    3504     unsigned                cVerbosity              = 0;
    3505     RTDIGESTTYPE            enmSigType              = RTDIGESTTYPE_SHA1;
    3506     bool                    fReplaceExisting        = true;
    3507     bool                    fNoSigningTime          = false;
    3508     SignToolKeyPair         SigningCertKey("signing", true);
    3509     RTCRSTORE               hAddCerts               = NIL_RTCRSTORE; /* leaked if returning directly (--help, --version) */
    3510     bool                    fTimestampTypeOld       = true;
    3511     SignToolKeyPair         TimestampCertKey("timestamp");
    3512     RTTIMESPEC              SigningTime;
    3513     RTTimeNow(&SigningTime);
    3514 
    3515     RTGETOPTSTATE   GetState;
    3516     int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
    3517     AssertRCReturn(rc, RTEXITCODE_FAILURE);
    3518 
    3519     RTEXITCODE      rcExit = RTEXITCODE_SUCCESS;
    3520     RTGETOPTUNION   ValueUnion;
    3521     int             ch;
    3522     while ((ch = RTGetOpt(&GetState, &ValueUnion)))
    3523     {
    3524         RTEXITCODE rcExit2 = RTEXITCODE_SUCCESS;
    3525         switch (ch)
    3526         {
    3527             OPT_CERT_KEY_SWITCH_CASES(SigningCertKey,   1000, ch, ValueUnion, rcExit2);
    3528             OPT_CERT_KEY_SWITCH_CASES(TimestampCertKey, 1020, ch, ValueUnion, rcExit2);
    3529             case 't':                       rcExit2 = HandleOptSignatureType(&enmSigType, ValueUnion.psz); break;
    3530             case 'a':                       fReplaceExisting = false; break;
    3531             case OPT_NO_SIGNING_TIME:       fNoSigningTime = true; break;
    3532             case OPT_ADD_CERT:              rcExit2 = HandleOptAddCert(&hAddCerts, ValueUnion.psz); break;
    3533             case OPT_TIMESTAMP_TYPE:        rcExit2 = HandleOptTimestampType(&fTimestampTypeOld, ValueUnion.psz); break;
    3534             case OPT_TIMESTAMP_OVERRIDE:    rcExit2 = HandleOptTimestampOverride(&SigningTime, ValueUnion.psz); break;
    3535             case 'v':                       cVerbosity++; break;
    3536             case 'V':                       return HandleVersion(cArgs, papszArgs);
    3537             case 'h':                       return HelpSignExe(g_pStdOut, RTSIGNTOOLHELP_FULL);
    3538 
    3539             case VINF_GETOPT_NOT_OPTION:
    3540                 /* Do final certificate and key option processing (first file only). */
    3541                 rcExit2 = SigningCertKey.finalizeOptions(cVerbosity);
    3542                 if (rcExit2 == RTEXITCODE_SUCCESS)
    3543                     rcExit2 = TimestampCertKey.finalizeOptions(cVerbosity);
    3544                 if (rcExit2 == RTEXITCODE_SUCCESS)
    3545                 {
    3546                     /* Do the work: */
    3547                     SIGNTOOLPKCS7 Cat;
    3548                     rcExit2 = SignToolPkcs7_InitFromFile(&Cat, ValueUnion.psz, cVerbosity);
    3549                     if (rcExit2 == RTEXITCODE_SUCCESS)
    3550                     {
    3551                         rcExit2 = SignToolPkcs7_AddOrReplaceCatSignature(&Cat, cVerbosity, enmSigType, fReplaceExisting,
    3552                                                                          fNoSigningTime, &SigningCertKey, hAddCerts,
    3553                                                                          fTimestampTypeOld, SigningTime, &TimestampCertKey);
    3554                         if (rcExit2 == RTEXITCODE_SUCCESS)
    3555                             rcExit2 = SignToolPkcs7_Encode(&Cat, cVerbosity);
    3556                         if (rcExit2 == RTEXITCODE_SUCCESS)
    3557                             rcExit2 = SignToolPkcs7_WriteSignatureToFile(&Cat, ValueUnion.psz, cVerbosity);
    3558                         SignToolPkcs7_Delete(&Cat);
    3559                     }
     3607                    else
     3608                        rcExit2 = RTEXITCODE_FAILURE;
    35603609                    if (rcExit2 != RTEXITCODE_SUCCESS && rcExit == RTEXITCODE_SUCCESS)
    35613610                        rcExit = rcExit2;
     
    51595208#ifndef IPRT_IN_BUILD_TOOL
    51605209    { "add-timestamp-exe-signature",    HandleAddTimestampExeSignature,     HelpAddTimestampExeSignature },
    5161     { "sign-exe",                       HandleSignExe,                      HelpSignExe  },
    5162     { "sign-cat",                       HandleSignCat,                      HelpSignCat  },
     5210    { "sign",                           HandleSign,                         HelpSign },
    51635211#endif
    51645212#ifndef IPRT_IN_BUILD_TOOL
Note: See TracChangeset for help on using the changeset viewer.

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