VirtualBox

Ignore:
Timestamp:
Apr 28, 2020 9:56:41 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
137603
Message:

bugre:9699. Added the command "signova" into VBoxManage.

Location:
trunk/src/VBox/Frontends/VBoxManage
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp

    r82968 r84032  
    147147    { "import",             USAGE_IMPORTAPPLIANCE,  VBMG_CMD_TODO, handleImportAppliance,      0 },
    148148    { "export",             USAGE_EXPORTAPPLIANCE,  VBMG_CMD_TODO, handleExportAppliance,      0 },
     149    { "signova",            USAGE_S_NEWCMD,         VBMG_CMD_TODO, handleSignAppliance,        0 },
    149150#ifdef VBOX_WITH_NETFLT
    150151    { "hostonlyif",         USAGE_HOSTONLYIFS,      VBMG_CMD_TODO, handleHostonlyIf,           0 },
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h

    r82968 r84032  
    314314RTEXITCODE handleStorageController(HandlerArg *a);
    315315
    316 // VBoxManageImport.cpp
     316// VBoxManageAppliance.cpp
    317317RTEXITCODE handleImportAppliance(HandlerArg *a);
    318318RTEXITCODE handleExportAppliance(HandlerArg *a);
     319RTEXITCODE handleSignAppliance(HandlerArg *a);
    319320
    320321// VBoxManageSnapshot.cpp
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp

    r82968 r84032  
    3030#include <VBox/com/errorprint.h>
    3131#include <VBox/com/VirtualBox.h>
     32#include <VBox/log.h>
     33#include <VBox/param.h>
     34
     35#include <VBox/version.h>
     36#include <revision-generated.h> /* VBOX_SVN_REV - PCH prevents putting it in DEFS. */
    3237
    3338#include <list>
     
    3540#endif /* !VBOX_ONLY_DOCS */
    3641
    37 #include <iprt/stream.h>
    3842#include <iprt/getopt.h>
    3943#include <iprt/ctype.h>
    4044#include <iprt/path.h>
    4145#include <iprt/file.h>
    42 
    43 #include <VBox/log.h>
    44 #include <VBox/param.h>
     46#include <iprt/err.h>
     47#include <iprt/zip.h>
     48#include <iprt/stream.h>
     49#include <iprt/vfs.h>
     50#include <iprt/manifest.h>
     51#include <iprt/crypto/digest.h>
     52#include <iprt/crypto/x509.h>
     53#include <iprt/crypto/pkcs7.h>
     54#include <iprt/crypto/store.h>
     55#include <iprt/crypto/spc.h>
     56#include <iprt/crypto/key.h>
     57#include <iprt/crypto/pkix.h>
     58
     59
    4560
    4661#include "VBoxManage.h"
     
    17721787}
    17731788
     1789
     1790RTEXITCODE handleSignAppliance(HandlerArg *arg)
     1791{
     1792    HRESULT hrc = S_OK;
     1793
     1794    static const RTGETOPTDEF s_aOptions[] =
     1795    {
     1796        { "--private-key-form",         'k', RTGETOPT_REQ_STRING },
     1797        { "--private-key-password",     'p', RTGETOPT_REQ_STRING },
     1798        { "--private-key-password-file",'f', RTGETOPT_REQ_STRING },
     1799        { "--cert-file",                'c', RTGETOPT_REQ_STRING },
     1800        { "--intermediate-cert-file",   'i', RTGETOPT_REQ_STRING },
     1801        { "--out-cert",                 'o', RTGETOPT_REQ_NOTHING },
     1802        { "--pkcs7",                    's', RTGETOPT_REQ_NOTHING },
     1803        { "--no-pkcs7",                 'S', RTGETOPT_REQ_NOTHING },
     1804        { "--force",                    'F', RTGETOPT_REQ_NOTHING },
     1805        { "--dry-run",                  'd', RTGETOPT_REQ_NOTHING },
     1806        { "help",                       1001, RTGETOPT_REQ_NOTHING },
     1807        { "--help",                     1002, RTGETOPT_REQ_NOTHING }
     1808    };
     1809
     1810    RTGETOPTSTATE GetState;
     1811    RTGETOPTUNION ValueUnion;
     1812
     1813    int rc = RTGetOptInit(&GetState, arg->argc, arg->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
     1814    AssertRCReturn(rc, RTEXITCODE_FAILURE);
     1815    if (arg->argc == 1)
     1816    {
     1817        RTPrintf("Empty command parameter list, show help.\n");
     1818        printHelp(g_pStdOut);
     1819        return RTEXITCODE_SUCCESS;
     1820    }
     1821
     1822    Utf8Str strOvfFilename;
     1823    Utf8Str strPrivateKeyForm;
     1824    Utf8Str strPrivateKeyPassword;
     1825    Utf8Str strPrivateKeyPasswordFile;
     1826    Utf8Str strX509CertificateFile;
     1827    Utf8Str strInterimCertificateFile;
     1828    bool    fOutCert = false; // the default
     1829    bool    fPKCS7 = false; // the default
     1830    bool    fResign = false; // the default
     1831    bool    fDry = false; // the default
     1832    com::SafeArray<BSTR>  parameters;
     1833
     1834    int c;
     1835    while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
     1836    {
     1837        switch (c)
     1838        {
     1839            case 'k':
     1840                strPrivateKeyForm=ValueUnion.psz;
     1841                break;
     1842
     1843            case 'p':
     1844                strPrivateKeyPassword=ValueUnion.psz;
     1845                break;
     1846
     1847            case 'f':
     1848                strPrivateKeyPasswordFile=ValueUnion.psz;
     1849                break;
     1850
     1851            case 'c':
     1852                strX509CertificateFile=ValueUnion.psz;
     1853                break;
     1854
     1855            case 'i':
     1856                strInterimCertificateFile=ValueUnion.psz;
     1857                break;
     1858
     1859            case 'o':
     1860                fOutCert = true;
     1861                break;
     1862
     1863            case 's':
     1864                fPKCS7 = true;
     1865                break;
     1866
     1867            case 'F':
     1868                fResign = true;
     1869                break;
     1870
     1871            case 'd':
     1872                fDry = true;
     1873                break;
     1874
     1875            case 1001:
     1876            case 1002:
     1877                printHelp(g_pStdOut);
     1878                return RTEXITCODE_SUCCESS;
     1879
     1880            case VINF_GETOPT_NOT_OPTION:
     1881                if (strOvfFilename.isEmpty())
     1882                    strOvfFilename = ValueUnion.psz;
     1883                else
     1884                    return errorGetOpt(c, &ValueUnion);
     1885                break;
     1886
     1887            default:
     1888                return errorGetOpt(c, &ValueUnion);
     1889        }
     1890    }
     1891
     1892    Utf8Str strManifestData;
     1893    Utf8Str strManifestName;
     1894    Utf8Str strAppliancePath;
     1895    Utf8Str strApplianceFullPath;
     1896
     1897    do
     1898    {
     1899        ComPtr<IAppliance> pAppliance;
     1900        CHECK_ERROR_BREAK(arg->virtualBox, CreateAppliance(pAppliance.asOutParam()));
     1901
     1902        char *pszAbsFilePath = RTPathAbsDup(strOvfFilename.c_str());
     1903
     1904        ComPtr<IProgress> progressRead;
     1905        CHECK_ERROR_BREAK(pAppliance, Read(Bstr(pszAbsFilePath).raw(), progressRead.asOutParam()));
     1906        RTStrFree(pszAbsFilePath);
     1907
     1908        hrc = showProgress(progressRead);
     1909        CHECK_PROGRESS_ERROR_RET(progressRead, ("Appliance read failed"), RTEXITCODE_FAILURE);
     1910
     1911        /* fetch the path, there is stuff like username/password removed if any */
     1912        Bstr path;
     1913        CHECK_ERROR_BREAK(pAppliance, COMGETTER(Path)(path.asOutParam()));
     1914
     1915        strAppliancePath = path;
     1916        strApplianceFullPath = strAppliancePath;
     1917        strAppliancePath.stripFilename();
     1918
     1919        RTPrintf("The original OVA package folder is %s\n\n", strAppliancePath.c_str());
     1920
     1921        /* fetch the manifest */
     1922        Bstr manifest;
     1923        Bstr manifestName;
     1924        CHECK_ERROR_BREAK(pAppliance, GetManifest(manifest.asOutParam(), manifestName.asOutParam()));
     1925
     1926        strManifestData = manifest;
     1927        strManifestName = manifestName;
     1928
     1929        if (strManifestName.isEmpty() || strManifestData.isEmpty())
     1930        {
     1931            RTPrintf("Manifest file wasn't found in the OVA package %s\n\n", strApplianceFullPath.c_str());
     1932            hrc = E_FAIL;
     1933        }
     1934
     1935    }while (0);
     1936
     1937    if (FAILED(hrc))
     1938        return RTEXITCODE_FAILURE;
     1939
     1940
     1941    /* Read the private key */
     1942    RTCRKEY hPrivateKey;
     1943    RTERRINFO ErrInfo;
     1944    uint32_t fFlags = 0;
     1945
     1946    if (strPrivateKeyForm.equalsIgnoreCase("pem"))
     1947        fFlags = RTCRPEMREADFILE_F_VALID_MASK;//|RTCRKEYFROM_F_VALID_MASK;
     1948
     1949    /* check the key file existence */
     1950    if (!RTFileExists(strPrivateKeyPasswordFile.c_str()))
     1951        return RTMsgErrorExit(RTEXITCODE_FAILURE, "The file %s with a private key wasn't found",
     1952                              strPrivateKeyPasswordFile.c_str());
     1953
     1954    rc = RTCrKeyCreateFromFile(&hPrivateKey, 0, strPrivateKeyPasswordFile.c_str(), strPrivateKeyPassword.c_str(), &ErrInfo);
     1955    if (RT_SUCCESS(rc))
     1956    {
     1957        RTPrintf("Reading the private key from %s was done.\n\n", strPrivateKeyPasswordFile.c_str());
     1958
     1959        /* check the certificate file existence */
     1960        if (!RTFileExists(strX509CertificateFile.c_str()))
     1961        {
     1962            RTCrKeyRelease(hPrivateKey);
     1963            return RTMsgErrorExit(RTEXITCODE_FAILURE, "The file %s with a X509 certificate wasn't found",
     1964                                  strX509CertificateFile.c_str());
     1965        }
     1966
     1967        /* Read the certificate */
     1968        RTCRX509CERTIFICATE     Certificate;
     1969        rc = RTCrX509Certificate_ReadFromFile(&Certificate, strX509CertificateFile.c_str(), 0, &g_RTAsn1DefaultAllocator,
     1970                                              &ErrInfo);
     1971        if (RT_FAILURE(rc))
     1972        {
     1973            RTCrKeyRelease(hPrivateKey);
     1974            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error reading certificate from %s: %Rrc - %s",
     1975                                  strX509CertificateFile.c_str(), rc, ErrInfo.pszMsg);
     1976        }
     1977
     1978        RTPrintf("Reading the certificate from %s was done.\n\n", strX509CertificateFile.c_str());
     1979
     1980        /*
     1981         * Get the manifest from Appliance and sign it.
     1982         * We have the private key, the password, the certificate.
     1983         * Also it's needed a digist algorithm SHA1/SHA256/SHA512.
     1984         * OVF2.0 standard proposes to use SHA256.
     1985         */
     1986
     1987        RTDIGESTTYPE digestType = RTDIGESTTYPE_SHA256;
     1988        RTMANIFEST hManifest;
     1989        RTCRDIGEST hDigest;
     1990
     1991        rc = RTManifestCreate(0 /*fFlags*/, &hManifest);
     1992        if (RT_FAILURE(rc))
     1993        {
     1994            RTCrKeyRelease(hPrivateKey);
     1995            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error manifest creation: %Rrc", rc);
     1996        }
     1997
     1998        /* Calc the digest of the manifest using the algorithm found above. */
     1999        rc = RTCrDigestCreateByType(&hDigest, digestType);
     2000        if (RT_SUCCESS(rc))
     2001        {
     2002            rc = RTCrDigestUpdate(hDigest, strManifestData.c_str(), strManifestData.length());
     2003            if (RT_SUCCESS(rc))
     2004            {
     2005                uint8_t const * bHash =  RTCrDigestGetHash(hDigest);
     2006
     2007                char szDigest[_4K];
     2008                rc = RTSha256ToString(bHash, szDigest, sizeof(szDigest));
     2009                RTPrintf("The digest of manifest is:\n%s\n\n", szDigest);
     2010
     2011                PCRTASN1DYNTYPE pParameters = NULL;
     2012
     2013                char   signatureBuf[_16K];
     2014                size_t cbSignature = sizeof(signatureBuf);
     2015                rc= RTCrPkixPubKeySignDigest(&Certificate.SignatureAlgorithm.Algorithm,
     2016                                              hPrivateKey,
     2017                                              pParameters,
     2018                                              hDigest,
     2019                                              0,
     2020                                              signatureBuf,
     2021                                              &cbSignature,
     2022                                              &ErrInfo);
     2023                if (RT_SUCCESS(rc))
     2024                {
     2025                    char szSignature[_4K];
     2026                    RTStrPrintHexBytes(szSignature, sizeof(szSignature), signatureBuf, cbSignature, 0 /*fFlags*/);
     2027
     2028                    /* Verify the signature back using the public key information from the certificate */
     2029                    rc = RTCrPkixPubKeyVerifySignedDigestByCertPubKeyInfo(&Certificate.TbsCertificate.SubjectPublicKeyInfo,
     2030                                                                          signatureBuf, cbSignature, hDigest, &ErrInfo);
     2031                    if (RT_FAILURE(rc))
     2032                    {
     2033                        /* Dont' forget */
     2034                        RTCrDigestRelease(hDigest);
     2035                        RTCrKeyRelease(hPrivateKey);
     2036                        if (rc == VERR_CR_PKIX_SIGNATURE_MISMATCH)
     2037                            return RTMsgErrorExit(RTEXITCODE_FAILURE, "The manifest signature does not match", rc);
     2038
     2039                        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error validating the manifest signature (%Rrc, %s)",
     2040                                              rc, ErrInfo.pszMsg);
     2041                    }
     2042                    else
     2043                        RTPrintf("The manifest signature was validated successfully\n\n");
     2044
     2045                    /*
     2046                     * Preparing the digest signature according to OVF2.0 standard.
     2047                     * Only SHA1 and SHA256 are supported for now.
     2048                     */
     2049                    Utf8Str strDigestSignature;
     2050
     2051                    switch (digestType)
     2052                    {
     2053                        case RTDIGESTTYPE_SHA1:
     2054                            strDigestSignature.append("SHA1");
     2055                            break;
     2056                        case RTDIGESTTYPE_SHA256:
     2057                        default:
     2058                            strDigestSignature.append("SHA256");
     2059                            break;
     2060                    }
     2061
     2062                    strDigestSignature.append('(').append(strManifestName).append(')').append(" = ");
     2063                    strDigestSignature.append(szSignature);
     2064
     2065                    /*
     2066                     * Especially add a new line character to avoid placing the certificate on the same line
     2067                     * with the digest signature.
     2068                     */
     2069                    strDigestSignature.append('\n');
     2070
     2071                    RTPrintf("The signed digest is:\n%s\n", strDigestSignature.c_str());
     2072
     2073                    /* Just stop here in the case of dry-run scenario */
     2074                    if (fDry)
     2075                    {
     2076                        /* Dont' forget */
     2077                        RTCrDigestRelease(hDigest);
     2078                        RTCrKeyRelease(hPrivateKey);
     2079                        return RTEXITCODE_SUCCESS;
     2080                    }
     2081
     2082                    /* Make up the certificate name */
     2083                    const char *pszSuffix = strrchr(strManifestName.c_str(), '.');
     2084                    Utf8Str strOVFCertificateName = Utf8Str(strManifestName.c_str(), pszSuffix - strManifestName.c_str());
     2085                    strOVFCertificateName.append(".cert");
     2086
     2087                    /* Create a memory I/O stream and write the digest signature and the certificate to it. */
     2088                    RTVFSIOSTREAM hVfsIosOVFCertificate;
     2089
     2090                    rc = RTVfsMemIoStrmCreate(NIL_RTVFSIOSTREAM, _1K, &hVfsIosOVFCertificate);
     2091                    if (RT_SUCCESS(rc))
     2092                    {
     2093                        size_t cbWritten = 0;
     2094                        rc = RTVfsIoStrmWrite(hVfsIosOVFCertificate, strDigestSignature.c_str(), strDigestSignature.length(),
     2095                                              true /*fBlocking*/, &cbWritten);
     2096                        if (RT_SUCCESS(rc))
     2097                        {
     2098                            Utf8Str strX509CertificateContent;
     2099                            /* Open and read the passed certificate file as a standard file */
     2100                            RTVFSFILE     hVfsOriginalX509Certificate;
     2101                            rc = RTVfsFileOpenNormal(strX509CertificateFile.c_str(),
     2102                                                     RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE,
     2103                                                     &hVfsOriginalX509Certificate);
     2104                            if (RT_SUCCESS(rc))
     2105                            {
     2106                                for (;;)
     2107                                {
     2108                                    char   abBuf[_4K];
     2109                                    size_t cbRead;
     2110                                    rc = RTVfsFileRead(hVfsOriginalX509Certificate, abBuf, sizeof(abBuf), &cbRead);
     2111                                    if (RT_SUCCESS(rc))
     2112                                    {
     2113                                        bool const fEof = rc == VINF_EOF;
     2114                                        strX509CertificateContent.append(abBuf, cbRead);
     2115                                        if (fEof)
     2116                                            break;
     2117                                    }
     2118                                    else
     2119                                        break;
     2120                                }
     2121                            }
     2122                            else
     2123                                RTPrintf("Reading the certificate from the file %s failed (%Rrc)",
     2124                                         strX509CertificateFile.c_str(), rc);
     2125
     2126                            /* Dont' forget */
     2127                            RTVfsFileRelease(hVfsOriginalX509Certificate);
     2128
     2129                            if (RT_SUCCESS(rc))
     2130                            {
     2131                                cbWritten = 0;
     2132                                /* Write out the certificate into the stream */
     2133                                rc = RTVfsIoStrmWrite(hVfsIosOVFCertificate, strX509CertificateContent.c_str(),
     2134                                                      strX509CertificateContent.length(), true /*fBlocking*/, &cbWritten);
     2135
     2136                                if (RT_FAILURE(rc))
     2137                                    RTPrintf("RTVfsIoStrmWrite failed on adding the certificate into the stream (%Rrc)", rc);
     2138                            }
     2139                            else
     2140                                RTPrintf("Reading the certificate from the file %s failed (%Rrc)",
     2141                                         strX509CertificateFile.c_str(), rc);
     2142                        }
     2143                        else
     2144                            RTPrintf("RTVfsIoStrmWrite failed  on adding the digest into the stream (%Rrc)", rc);
     2145                    }
     2146                    else
     2147                        RTPrintf("RTVfsMemIoStrmCreate failed (%Rrc)", rc);
     2148
     2149                    if (RT_FAILURE(rc))
     2150                    {
     2151                        /* Dont' forget */
     2152                        RTVfsIoStrmRelease(hVfsIosOVFCertificate);
     2153                        return RTEXITCODE_FAILURE;
     2154                    }
     2155
     2156
     2157                    /* Make up new appliance name */
     2158                    const char *pszSuffix1 = strrchr(strManifestName.c_str(), '.');
     2159                    Utf8Str strSignedOVAName(strAppliancePath);
     2160                    strSignedOVAName.append(RTPATH_DELIMITER).append(strManifestName.c_str(),
     2161                                                                     pszSuffix1 - strManifestName.c_str());
     2162                    strSignedOVAName.append("-signed.ova");
     2163
     2164                    RTPrintf("The path for new OVA signed package is '%s'\n\n", strSignedOVAName.c_str());
     2165
     2166                    /*
     2167                     * Open new OVA file (it's a standard TAR file) as a file stream
     2168                     */
     2169                    RTVFSIOSTREAM hVfsIosSignedOVAPackage;
     2170                    rc = RTVfsIoStrmOpenNormal(strSignedOVAName.c_str(),
     2171                                               RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE,
     2172                                               &hVfsIosSignedOVAPackage);
     2173                    if (RT_SUCCESS(rc))
     2174                    {
     2175                        RTVFSFSSTREAM hVfsFssOVADest;
     2176                        rc = RTZipTarFsStreamToIoStream(hVfsIosSignedOVAPackage, RTZIPTARFORMAT_USTAR,
     2177                                                        0 /*fFlags*/, &hVfsFssOVADest);
     2178                        RTVfsIoStrmRelease(hVfsIosSignedOVAPackage);
     2179
     2180                        if (RT_SUCCESS(rc))
     2181                        {
     2182                            bool fCertPresence = false;
     2183                            RTZipTarFsStreamSetFileMode(hVfsFssOVADest, 0660, 0440);
     2184
     2185                            /*
     2186                             * Open the original OVA file (it's a standard TAR file) as a file stream
     2187                             */
     2188                            RTVFSIOSTREAM hVfsIosOVASrc;
     2189                            rc = RTVfsIoStrmOpenNormal(strApplianceFullPath.c_str(),
     2190                                                       RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN,
     2191                                                       &hVfsIosOVASrc);
     2192                            if (RT_SUCCESS(rc))
     2193                            {
     2194                                RTVFSFSSTREAM hVfsFssOVASrc;
     2195                                rc = RTZipTarFsStreamFromIoStream(hVfsIosOVASrc, 0 /*fFlags*/, &hVfsFssOVASrc);
     2196                                /* Dont' forget */
     2197                                RTVfsIoStrmRelease(hVfsIosOVASrc);
     2198
     2199                                if (RT_SUCCESS(rc))
     2200                                {
     2201                                    for (;;)
     2202                                    {
     2203                                        char *pszName = NULL;
     2204                                        RTVFSOBJTYPE enmType;
     2205                                        RTVFSOBJ     hVfsObj;
     2206                                        hrc = S_OK;
     2207                                        rc = RTVfsFsStrmNext(hVfsFssOVASrc, &pszName, &enmType, &hVfsObj);
     2208                                        if (RT_FAILURE(rc))
     2209                                        {
     2210                                            if (rc != VERR_EOF)
     2211                                                RTPrintf("Error reading the OVA file '%s' (%Rrc)",
     2212                                                         strApplianceFullPath.c_str(), rc);
     2213                                            else
     2214                                                rc = VINF_SUCCESS;
     2215
     2216                                            break;
     2217                                        }
     2218
     2219                                        /*
     2220                                         * in the case when the certificate has been already presented in the OVA package
     2221                                         */
     2222                                        if (strOVFCertificateName.equals(pszName))
     2223                                        {
     2224                                            RTPrintf("Some certificate has already presented in the OVA package\n\n");
     2225                                            fCertPresence = true;//remember for later usage
     2226                                            /* if the flag --force has been set just skip it and go further */
     2227                                            if (fResign)
     2228                                                continue;
     2229                                        }
     2230
     2231                                        /** todo: some progress object should be added here to display the action progress */
     2232                                        /* Read the input stream and add the content into the output stream */
     2233                                        rc = RTVfsFsStrmAdd(hVfsFssOVADest, pszName, hVfsObj, 0 /*fFlags*/);
     2234                                        if (RT_FAILURE(rc))
     2235                                            RTPrintf("RTVfsFsStrmAdd failed for the %s (%Rrc)", pszName, rc);
     2236
     2237                                        /* Free resources */
     2238                                        RTVfsObjRelease(hVfsObj);
     2239                                        RTStrFree(pszName);
     2240
     2241                                        if (RT_FAILURE(rc))
     2242                                        {
     2243                                            RTPrintf("Error writing to new OVA package '%s' (%Rrc)",
     2244                                                     strSignedOVAName.c_str(), rc);
     2245                                            break;
     2246                                        }
     2247                                    }
     2248
     2249                                    /* Dont' forget */
     2250                                    RTVfsFsStrmRelease(hVfsFssOVASrc);
     2251                                }
     2252                                else
     2253                                    RTPrintf("Error reading the OVA file '%s' (%Rrc)", strApplianceFullPath.c_str(), rc);
     2254                            }
     2255                            else
     2256                                RTPrintf("Error opening the OVA file '%s' (%Rrc)", strApplianceFullPath.c_str(), rc);
     2257
     2258                            /*
     2259                             * Now add the digest signature into new OVA package
     2260                             */
     2261                            if (RT_SUCCESS(rc))
     2262                            {
     2263                                /* Add only if no cetificate or the flag fResign was set and certificate is presented */
     2264                                if ( !fCertPresence || (fCertPresence && fResign) )
     2265                                {
     2266                                    size_t cbWritten;
     2267                                    size_t cbRead;
     2268                                    RTFOFF off = RTVfsIoStrmTell(hVfsIosOVFCertificate);
     2269                                    void *pvBuf = RTMemAlloc(off);
     2270                                    size_t cbBuf = off;
     2271
     2272                                    rc = RTVfsIoStrmReadAt(hVfsIosOVFCertificate, 0, pvBuf, cbBuf,
     2273                                                           true /*fBlocking*/, &cbRead);
     2274                                    if (RT_SUCCESS(rc))
     2275                                    {
     2276                                        RTVFSIOSTREAM hVfsIosSrc;
     2277                                        rc = RTVfsIoStrmFromBuffer(RTFILE_O_READ, pvBuf, cbRead, &hVfsIosSrc);
     2278                                        RTVFSOBJ hVfsObjCert = RTVfsObjFromIoStream(hVfsIosSrc);
     2279                                        RTVfsIoStrmRelease(hVfsIosSrc);
     2280
     2281                                        RTZipTarFsStreamSetOwner(hVfsFssOVADest, VBOX_VERSION_MAJOR, "vboxovf20");
     2282                                        RTZipTarFsStreamSetGroup(hVfsFssOVADest, VBOX_VERSION_MINOR,
     2283                                                                 "vbox_v" RT_XSTR(VBOX_VERSION_MAJOR) "."
     2284                                                                 RT_XSTR(VBOX_VERSION_MINOR) "."
     2285                                                                 RT_XSTR(VBOX_VERSION_BUILD) "r"
     2286                                                                 RT_XSTR(VBOX_SVN_REV) "\0");
     2287
     2288                                        /* Write out the certificate into the stream */
     2289                                        rc = RTVfsFsStrmAdd(hVfsFssOVADest, strOVFCertificateName.c_str(),
     2290                                                            hVfsObjCert, 0 /*fFlags*/);
     2291                                        if (RT_FAILURE(rc))
     2292                                            RTPrintf("RTVfsFsStrmAdd failed for the %s (%Rrc)",
     2293                                                     strOVFCertificateName.c_str(), rc);
     2294
     2295                                        /* Dont' forget */
     2296                                        RTVfsObjRelease(hVfsObjCert);
     2297
     2298                                        /* Save the OVA certificate file next to the original OVA package */
     2299                                        if (fOutCert)
     2300                                        {
     2301                                            Utf8Str strCertificateFileFullPath(strAppliancePath);
     2302                                            strCertificateFileFullPath.append(RTPATH_DELIMITER).
     2303                                                                       append(strOVFCertificateName.c_str());
     2304
     2305                                            RTVFSIOSTREAM hVfsIosCertFile;
     2306                                            rc = RTVfsIoStrmOpenNormal(strCertificateFileFullPath.c_str(),
     2307                                                                       RTFILE_O_CREATE_REPLACE |
     2308                                                                       RTFILE_O_WRITE |
     2309                                                                       RTFILE_O_DENY_NONE,
     2310                                                                       &hVfsIosCertFile);
     2311                                            if (RT_SUCCESS(rc))
     2312                                            {
     2313                                                /* Write out the certificate into the file */
     2314                                                rc = RTVfsIoStrmWrite(hVfsIosCertFile, pvBuf,
     2315                                                                      cbBuf, true /*fBlocking*/, &cbWritten);
     2316                                                if (RT_FAILURE(rc))
     2317                                                    RTPrintf("Error writing the certificate file '%s' (%Rrc)",
     2318                                                             strCertificateFileFullPath.c_str(), rc);
     2319
     2320                                                /* Dont' forget */
     2321                                                RTVfsIoStrmFlush(hVfsIosCertFile);
     2322                                                RTVfsIoStrmRelease(hVfsIosCertFile);
     2323                                            }
     2324                                            else
     2325                                                RTPrintf("Error opening the certificate file '%s' (%Rrc)",
     2326                                                         strCertificateFileFullPath.c_str(), rc);
     2327                                        }
     2328                                    }
     2329                                    else
     2330                                        RTPrintf("Error writing the certificate file '%s' (%Rrc)",
     2331                                                 strOVFCertificateName.c_str(), rc);
     2332
     2333                                    /* Dont' forget */
     2334                                    RTMemFree(pvBuf);
     2335                                }
     2336                            }
     2337
     2338                            /* Dont' forget */
     2339                            RTVfsFsStrmRelease(hVfsFssOVADest);
     2340                        }
     2341                        else
     2342                            RTPrintf("Failed create TAR creator for '%s' (%Rrc)", strSignedOVAName.c_str(), rc);
     2343                    }
     2344                    else
     2345                        RTPrintf("Error opening new OVA signed package '%s'\n", strSignedOVAName.c_str());
     2346
     2347                    /* Dont' forget */
     2348                     RTVfsIoStrmRelease(hVfsIosOVFCertificate);
     2349                }
     2350                else
     2351                    RTPrintf("Error signing the digest of manifest: %Rrc", rc);
     2352            }
     2353            else
     2354                RTPrintf("Error updating the digest: %Rrc", rc);
     2355        }
     2356        else
     2357            RTPrintf("Error digest creation: %Rrc", rc);
     2358
     2359        /* Don't forget */
     2360        RTCrDigestRelease(hDigest);
     2361        RTCrKeyRelease(hPrivateKey);
     2362    }
     2363    else
     2364        RTPrintf("Error reading the private key from %s: %Rrc - %s", strPrivateKeyPasswordFile.c_str(), rc, ErrInfo.pszMsg);
     2365
     2366    /* Dont' forget */
     2367    if (RT_SUCCESS(rc))
     2368        hrc = S_OK;
     2369
     2370    return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
     2371}
     2372
    17742373#endif /* !VBOX_ONLY_DOCS */
    1775 
Note: See TracChangeset for help on using the changeset viewer.

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