VirtualBox

Changeset 84231 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
May 10, 2020 12:53:10 AM (5 years ago)
Author:
vboxsync
Message:

VBoxManage/signova: Early implementation of PKCS#7/CMS signature. IPRT cannot read it yet, so command fails at present. bugref:9699

File:
1 edited

Legend:

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

    r84212 r84231  
    19831983
    19841984/**
     1985 * For testing the decoding side.
     1986 */
     1987static int doCheckPkcs7Signature(void const *pvSignature, size_t cbSignature, PCRTCRX509CERTIFICATE pCertificate,
     1988                                 RTCRSTORE hIntermediateCerts, unsigned iVerbosity, PRTERRINFOSTATIC pErrInfo)
     1989{
     1990    RTASN1CURSORPRIMARY PrimaryCursor;
     1991    RTAsn1CursorInitPrimary(&PrimaryCursor, pvSignature, (uint32_t)cbSignature, RTErrInfoInitStatic(pErrInfo),
     1992                            &g_RTAsn1DefaultAllocator, 0, "Signature");
     1993
     1994    RTCRPKCS7CONTENTINFO ContentInfo;
     1995    RT_ZERO(ContentInfo);
     1996    int rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &ContentInfo, "CI");
     1997    if (RT_SUCCESS(rc))
     1998    {
     1999        if (iVerbosity > 5)
     2000            RTAsn1Dump(&ContentInfo.SeqCore.Asn1Core, 0 /*fFlags*/, 0 /*uLevel*/, RTStrmDumpPrintfV, g_pStdOut);
     2001
     2002        /*
     2003         * It must be signedData.
     2004         */
     2005        if (RTCrPkcs7ContentInfo_IsSignedData(&ContentInfo))
     2006        {
     2007            PRTCRPKCS7SIGNEDDATA pSignedData = ContentInfo.u.pSignedData;
     2008
     2009            /*
     2010             * Inside the signedData there must be just 'data'.
     2011             */
     2012            if (!strcmp(pSignedData->ContentInfo.ContentType.szObjId, RTCR_PKCS7_DATA_OID))
     2013            {
     2014                /*
     2015                 * Check that things add up.
     2016                 */
     2017                rc = RTCrPkcs7SignedData_CheckSanity(pSignedData,
     2018                                                     RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH
     2019                                                     | RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT,
     2020                                                     RTErrInfoInitStatic(pErrInfo), "SD");
     2021                if (RT_SUCCESS(rc))
     2022                {
     2023                    if (iVerbosity > 2)
     2024                        RTMsgInfo("  Successfully decoded the PKCS#7/CMS signature...");
     2025                    RT_NOREF(pCertificate, hIntermediateCerts);
     2026                }
     2027                else
     2028                    RTMsgError("RTCrPkcs7SignedData_CheckSanity failed on PKCS#7/CMS signature: %Rrc%RTeim",
     2029                               rc, &pErrInfo->Core);
     2030
     2031            }
     2032            else
     2033                rc = RTMsgErrorRc(VERR_WRONG_TYPE, "PKCS#7/CMS signature inner ContentType isn't 'data' but: %s",
     2034                                  pSignedData->ContentInfo.ContentType.szObjId);
     2035        }
     2036        else
     2037            rc = RTMsgErrorRc(VERR_WRONG_TYPE, "PKCS#7/CMD signature is not 'signedData': %s", ContentInfo.ContentType.szObjId);
     2038    }
     2039    else
     2040        RTMsgError("RTCrPkcs7ContentInfo_DecodeAsn1 failed to decode PKCS#7/CMS signature: %Rrc%RTemi", rc, &pErrInfo->Core);
     2041
     2042    RTCrPkcs7ContentInfo_Delete(&ContentInfo);
     2043    return rc;
     2044}
     2045
     2046
     2047/**
    19852048 * Creates a PKCS\#7 signature and appends it to the signature file in PEM
    19862049 * format.
    19872050 */
    19882051static int doAddPkcs7Signature(PCRTCRX509CERTIFICATE pCertificate, RTCRKEY hPrivateKey,
    1989                                unsigned cIntermediateCerts, const char **papszIntermediateCerts,
    1990                                RTCRDIGEST hDigest, PRTERRINFOSTATIC pErrInfo, RTVFSFILE hVfsFileSignature)
     2052                               unsigned cIntermediateCerts, const char **papszIntermediateCerts, RTVFSFILE hVfsFileManifest,
     2053                               unsigned iVerbosity, PRTERRINFOSTATIC pErrInfo, RTVFSFILE hVfsFileSignature)
    19912054{
    1992     RT_NOREF(pCertificate, hPrivateKey, cIntermediateCerts, papszIntermediateCerts, hDigest, pErrInfo, hVfsFileSignature);
    1993     RTPrintf("TODO: doAddPkcs7Signature\n");
    1994     return VINF_SUCCESS;
     2055    /*
     2056     * Add a blank line, just for good measure.
     2057     */
     2058    int rc = RTVfsFileWrite(hVfsFileManifest, " ", 1, NULL);
     2059    if (RT_FAILURE(rc))
     2060        return RTMsgErrorRc(rc, "RTVfsFileWrite/signature: %Rrc", rc);
     2061
     2062    /*
     2063     * Read the manifest into a single memory block.
     2064     */
     2065    uint64_t cbManifest;
     2066    rc = RTVfsFileQuerySize(hVfsFileManifest, &cbManifest);
     2067    if (RT_FAILURE(rc))
     2068        return RTMsgErrorRc(rc, "RTVfsFileQuerySize/manifest: %Rrc", rc);
     2069    if (cbManifest > _4M)
     2070        return RTMsgErrorRc(VERR_OUT_OF_RANGE, "Manifest is too big: %#RX64 bytes, max 4MiB", cbManifest);
     2071
     2072    void *pvManifest = RTMemAllocZ(cbManifest + 1);
     2073    if (!pvManifest)
     2074        return RTMsgErrorRc(VERR_NO_MEMORY, "Out of memory!");
     2075
     2076    rc = RTVfsFileReadAt(hVfsFileManifest, 0, pvManifest, (size_t)cbManifest, NULL);
     2077    if (RT_SUCCESS(rc))
     2078    {
     2079        /*
     2080         * Load intermediate certificates.
     2081         */
     2082        RTCRSTORE hIntermediateCerts = NIL_RTCRSTORE;
     2083        if (cIntermediateCerts)
     2084        {
     2085            rc = RTCrStoreCreateInMem(&hIntermediateCerts, cIntermediateCerts);
     2086            if (RT_SUCCESS(rc))
     2087            {
     2088                for (unsigned i = 0; i < cIntermediateCerts; i++)
     2089                {
     2090                    const char *pszFile = papszIntermediateCerts[i];
     2091                    rc = RTCrStoreCertAddFromFile(hIntermediateCerts, 0 /*fFlags*/, pszFile, &pErrInfo->Core);
     2092                    if (RT_FAILURE(rc))
     2093                    {
     2094                        RTMsgError("RTCrStoreCertAddFromFile failed on '%s': %Rrc%#RTeim", pszFile, rc, &pErrInfo->Core);
     2095                        break;
     2096                    }
     2097                }
     2098            }
     2099            else
     2100                RTMsgError("RTCrStoreCreateInMem failed: %Rrc%", rc);
     2101        }
     2102        if (RT_SUCCESS(rc))
     2103        {
     2104            /*
     2105             * Do a dry run to determin the size of the signed data.
     2106             */
     2107            size_t cbResult = 0;
     2108            rc = RTCrPkcs7SimpleSignSignedData(RTCRPKCS7SIGN_SD_F_DEATCHED | RTCRPKCS7SIGN_SD_F_NO_SMIME_CAP,
     2109                                               pCertificate, hPrivateKey, pvManifest, (size_t)cbManifest,
     2110                                               hIntermediateCerts, NULL /*pvResult*/, &cbResult, RTErrInfoInitStatic(pErrInfo));
     2111            if (rc == VERR_BUFFER_OVERFLOW)
     2112            {
     2113                /*
     2114                 * Allocate a buffer of the right size and do the real run.
     2115                 */
     2116                void *pvResult = RTMemAllocZ(cbResult);
     2117                if (pvResult)
     2118                {
     2119                    rc = RTCrPkcs7SimpleSignSignedData(RTCRPKCS7SIGN_SD_F_DEATCHED | RTCRPKCS7SIGN_SD_F_NO_SMIME_CAP,
     2120                                                       pCertificate, hPrivateKey, pvManifest, (size_t)cbManifest,
     2121                                                       NIL_RTCRSTORE, pvResult, &cbResult, RTErrInfoInitStatic(pErrInfo));
     2122                    if (RT_SUCCESS(rc))
     2123                    {
     2124                        /*
     2125                         * Add it to the signature file in PEM format.
     2126                         */
     2127                        rc = (int)RTCrPemWriteBlobToVfsFile(hVfsFileSignature, pvResult, cbResult, "CMS");
     2128                        if (RT_SUCCESS(rc))
     2129                        {
     2130                            if (iVerbosity > 1)
     2131                                RTMsgInfo("Created PKCS#7/CMS signature: %zu bytes.", cbResult);
     2132
     2133                            /*
     2134                             * Try decode and verify the signature.
     2135                             */
     2136                            rc = doCheckPkcs7Signature(pvResult, cbResult, pCertificate, hIntermediateCerts,
     2137                                                       iVerbosity, pErrInfo);
     2138                        }
     2139                        else
     2140                            RTMsgError("RTCrPemWriteBlobToVfsFile failed: %Rrc", rc);
     2141                    }
     2142                    RTMemFree(pvResult);
     2143                }
     2144                else
     2145                    rc = RTMsgErrorRc(VERR_NO_MEMORY, "Out of memory!");
     2146            }
     2147            else
     2148                RTMsgError("RTCrPkcs7SimpleSignSignedData failed: %Rrc%#RTeim", rc, &pErrInfo->Core);
     2149        }
     2150    }
     2151    else
     2152        RTMsgError("RTVfsFileReadAt failed: %Rrc", rc);
     2153    RTMemFree(pvManifest);
     2154    return rc;
    19952155}
    19962156
     
    20012161static int doTheOvaSigning(PRTCRX509CERTIFICATE pCertificate, RTCRKEY hPrivateKey, RTDIGESTTYPE enmDigestType,
    20022162                           const char *pszManifestName, RTVFSFILE hVfsFileManifest,
    2003                            bool fPkcs7, unsigned cIntermediateCerts, const char **papszIntermediateCerts,
     2163                           bool fPkcs7, unsigned cIntermediateCerts, const char **papszIntermediateCerts, unsigned iVerbosity,
    20042164                           PRTERRINFOSTATIC pErrInfo, PRTVFSFILE phVfsFileSignature)
    20052165{
     
    20622222                    if (RT_SUCCESS(rc))
    20632223                    {
     2224                        if (iVerbosity > 0)
     2225                            RTMsgInfo("Created OVA signature: %zu bytes, %s", cbSignature, RTCrDigestTypeToName(enmDigestType));
     2226
    20642227                        /*
    20652228                         * Create the output file.
     
    20792242                                    if (fPkcs7)
    20802243                                        rc = doAddPkcs7Signature(pCertificate, hPrivateKey, cIntermediateCerts,
    2081                                                                  papszIntermediateCerts, hDigest, pErrInfo, hVfsFileSignature);
     2244                                                                 papszIntermediateCerts, hVfsFileManifest, iVerbosity,
     2245                                                                 pErrInfo, hVfsFileSignature);
    20822246                                    if (RT_SUCCESS(rc))
    20832247                                    {
     
    22972461            RTVFSFILE hVfsFileSignature = NIL_RTVFSFILE;
    22982462            rc = doTheOvaSigning(&Certificate, hPrivateKey, enmDigestType, strManifestName.c_str(), hVfsFileManifest,
    2299                                  fPkcs7, cIntermediateCerts, apszIntermediateCerts, &ErrInfo, &hVfsFileSignature);
     2463                                 fPkcs7, cIntermediateCerts, apszIntermediateCerts, iVerbosity, &ErrInfo, &hVfsFileSignature);
    23002464
    23012465            /*
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