Changeset 84032 in vbox for trunk/src/VBox/Frontends/VBoxManage
- Timestamp:
- Apr 28, 2020 9:56:41 AM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 137603
- Location:
- trunk/src/VBox/Frontends/VBoxManage
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
r82968 r84032 147 147 { "import", USAGE_IMPORTAPPLIANCE, VBMG_CMD_TODO, handleImportAppliance, 0 }, 148 148 { "export", USAGE_EXPORTAPPLIANCE, VBMG_CMD_TODO, handleExportAppliance, 0 }, 149 { "signova", USAGE_S_NEWCMD, VBMG_CMD_TODO, handleSignAppliance, 0 }, 149 150 #ifdef VBOX_WITH_NETFLT 150 151 { "hostonlyif", USAGE_HOSTONLYIFS, VBMG_CMD_TODO, handleHostonlyIf, 0 }, -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
r82968 r84032 314 314 RTEXITCODE handleStorageController(HandlerArg *a); 315 315 316 // VBoxManage Import.cpp316 // VBoxManageAppliance.cpp 317 317 RTEXITCODE handleImportAppliance(HandlerArg *a); 318 318 RTEXITCODE handleExportAppliance(HandlerArg *a); 319 RTEXITCODE handleSignAppliance(HandlerArg *a); 319 320 320 321 // VBoxManageSnapshot.cpp -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
r82968 r84032 30 30 #include <VBox/com/errorprint.h> 31 31 #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. */ 32 37 33 38 #include <list> … … 35 40 #endif /* !VBOX_ONLY_DOCS */ 36 41 37 #include <iprt/stream.h>38 42 #include <iprt/getopt.h> 39 43 #include <iprt/ctype.h> 40 44 #include <iprt/path.h> 41 45 #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 45 60 46 61 #include "VBoxManage.h" … … 1772 1787 } 1773 1788 1789 1790 RTEXITCODE 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 1774 2373 #endif /* !VBOX_ONLY_DOCS */ 1775
Note:
See TracChangeset
for help on using the changeset viewer.