Beispiel #1
0
/**
 * Reads a certificate from a file, returning a context or a the handle to a
 * temporary memory store.
 *
 * @returns true on success, false on failure (error message written).
 * @param   pszCertFile         The name of the file containing the
 *                              certificates.
 * @param   ppOutCtx            Where to return the certificate context.
 * @param   phSrcStore          Where to return the handle to the temporary
 *                              memory store.
 */
static bool readCertFile(const char *pszCertFile, PCCERT_CONTEXT *ppOutCtx, HCERTSTORE *phSrcStore)
{
    *ppOutCtx   = NULL;
    *phSrcStore = NULL;

    bool    fRc = false;
    void   *pvFile;
    size_t  cbFile;
    int rc = RTFileReadAll(pszCertFile, &pvFile, &cbFile);
    if (RT_SUCCESS(rc))
    {
        *ppOutCtx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                                 (PBYTE)pvFile, (DWORD)cbFile);
        if (*ppOutCtx)
            fRc = true;
        else
        {
            /** @todo figure out if it's some other format... */
            RTMsgError("CertCreateCertificateContext returned %s parsing the content of '%s'",
                       errorToString(GetLastError()), pszCertFile);
        }
    }
    else
        RTMsgError("RTFileReadAll failed on '%s': %Rrc", pszCertFile, rc);
    RTFileReadAllFree(pvFile, cbFile);
    return fRc;
}
Beispiel #2
0
/**
 * Grows the buffer of a write stream.
 *
 * @returns IPRT status code.
 * @param   pStream             The stream.  Must be in write mode.
 * @param   cbAppending         The minimum number of bytes to grow the buffer
 *                              with.
 */
static int scmStreamGrowBuffer(PSCMSTREAM pStream, size_t cbAppending)
{
    size_t cbAllocated = pStream->cbAllocated;
    cbAllocated += RT_MAX(0x1000 + cbAppending, cbAllocated);
    cbAllocated = RT_ALIGN(cbAllocated, 0x1000);
    void *pvNew;
    if (!pStream->fFileMemory)
    {
        pvNew = RTMemRealloc(pStream->pch, cbAllocated);
        if (!pvNew)
            return pStream->rc = VERR_NO_MEMORY;
    }
    else
    {
        pvNew = RTMemDupEx(pStream->pch, pStream->off, cbAllocated - pStream->off);
        if (!pvNew)
            return pStream->rc = VERR_NO_MEMORY;
        RTFileReadAllFree(pStream->pch, pStream->cbAllocated);
        pStream->fFileMemory = false;
    }
    pStream->pch = (char *)pvNew;
    pStream->cbAllocated = cbAllocated;

    return VINF_SUCCESS;
}
RTDECL(int) RTCrPemFreeSections(PCRTCRPEMSECTION pSectionHead)
{
    while (pSectionHead != NULL)
    {
        PRTCRPEMSECTION pFree = (PRTCRPEMSECTION)pSectionHead;
        pSectionHead = pSectionHead->pNext;

        if (pFree->pMarker)
        {
            if (pFree->pbData)
            {
                RTMemFree(pFree->pbData);
                pFree->pbData = NULL;
                pFree->cbData = 0;
            }

            if (pFree->pszPreamble)
            {
                RTMemFree(pFree->pszPreamble);
                pFree->pszPreamble = NULL;
                pFree->cchPreamble = 0;
            }
        }
        else
        {
            RTFileReadAllFree(pFree->pbData, pFree->cbData);
            Assert(!pFree->pszPreamble);
        }
        pFree->pbData = NULL;
        pFree->cbData = 0;
    }
    return VINF_SUCCESS;
}
Beispiel #4
0
/**
 * Frees the resources associated with the stream.
 *
 * Nothing is happens to whatever the stream was initialized from or dumped to.
 *
 * @param   pStream             The stream to delete.
 */
void ScmStreamDelete(PSCMSTREAM pStream)
{
    if (pStream->pch)
    {
        if (pStream->fFileMemory)
            RTFileReadAllFree(pStream->pch, pStream->cbAllocated);
        else
            RTMemFree(pStream->pch);
        pStream->pch = NULL;
    }
    pStream->cbAllocated = 0;

    if (pStream->paLines)
    {
        RTMemFree(pStream->paLines);
        pStream->paLines = NULL;
    }
    pStream->cLinesAllocated = 0;
}
Beispiel #5
0
/** The verbosity level. */
static unsigned  g_cVerbosityLevel = 1;


static const char *errorToString(DWORD dwErr)
{
    switch (dwErr)
    {
#define MY_CASE(a_uConst)       case a_uConst: return #a_uConst;
        MY_CASE(CRYPT_E_MSG_ERROR);
        MY_CASE(CRYPT_E_UNKNOWN_ALGO);
        MY_CASE(CRYPT_E_OID_FORMAT);
        MY_CASE(CRYPT_E_INVALID_MSG_TYPE);
        MY_CASE(CRYPT_E_UNEXPECTED_ENCODING);
        MY_CASE(CRYPT_E_AUTH_ATTR_MISSING);
        MY_CASE(CRYPT_E_HASH_VALUE);
        MY_CASE(CRYPT_E_INVALID_INDEX);
        MY_CASE(CRYPT_E_ALREADY_DECRYPTED);
        MY_CASE(CRYPT_E_NOT_DECRYPTED);
        MY_CASE(CRYPT_E_RECIPIENT_NOT_FOUND);
        MY_CASE(CRYPT_E_CONTROL_TYPE);
        MY_CASE(CRYPT_E_ISSUER_SERIALNUMBER);
        MY_CASE(CRYPT_E_SIGNER_NOT_FOUND);
        MY_CASE(CRYPT_E_ATTRIBUTES_MISSING);
        MY_CASE(CRYPT_E_STREAM_MSG_NOT_READY);
        MY_CASE(CRYPT_E_STREAM_INSUFFICIENT_DATA);
        MY_CASE(CRYPT_I_NEW_PROTECTION_REQUIRED);
        MY_CASE(CRYPT_E_BAD_LEN);
        MY_CASE(CRYPT_E_BAD_ENCODE);
        MY_CASE(CRYPT_E_FILE_ERROR);
        MY_CASE(CRYPT_E_NOT_FOUND);
        MY_CASE(CRYPT_E_EXISTS);
        MY_CASE(CRYPT_E_NO_PROVIDER);
        MY_CASE(CRYPT_E_SELF_SIGNED);
        MY_CASE(CRYPT_E_DELETED_PREV);
        MY_CASE(CRYPT_E_NO_MATCH);
        MY_CASE(CRYPT_E_UNEXPECTED_MSG_TYPE);
        MY_CASE(CRYPT_E_NO_KEY_PROPERTY);
        MY_CASE(CRYPT_E_NO_DECRYPT_CERT);
        MY_CASE(CRYPT_E_BAD_MSG);
        MY_CASE(CRYPT_E_NO_SIGNER);
        MY_CASE(CRYPT_E_PENDING_CLOSE);
        MY_CASE(CRYPT_E_REVOKED);
        MY_CASE(CRYPT_E_NO_REVOCATION_DLL);
        MY_CASE(CRYPT_E_NO_REVOCATION_CHECK);
        MY_CASE(CRYPT_E_REVOCATION_OFFLINE);
        MY_CASE(CRYPT_E_NOT_IN_REVOCATION_DATABASE);
        MY_CASE(CRYPT_E_INVALID_NUMERIC_STRING);
        MY_CASE(CRYPT_E_INVALID_PRINTABLE_STRING);
        MY_CASE(CRYPT_E_INVALID_IA5_STRING);
        MY_CASE(CRYPT_E_INVALID_X500_STRING);
        MY_CASE(CRYPT_E_NOT_CHAR_STRING);
        MY_CASE(CRYPT_E_FILERESIZED);
        MY_CASE(CRYPT_E_SECURITY_SETTINGS);
        MY_CASE(CRYPT_E_NO_VERIFY_USAGE_DLL);
        MY_CASE(CRYPT_E_NO_VERIFY_USAGE_CHECK);
        MY_CASE(CRYPT_E_VERIFY_USAGE_OFFLINE);
        MY_CASE(CRYPT_E_NOT_IN_CTL);
        MY_CASE(CRYPT_E_NO_TRUSTED_SIGNER);
        MY_CASE(CRYPT_E_MISSING_PUBKEY_PARA);
        MY_CASE(CRYPT_E_OSS_ERROR);
        default:
        {
            PCRTCOMERRMSG pWinComMsg = RTErrCOMGet(dwErr);
            if (pWinComMsg)
                return pWinComMsg->pszDefine;

            static char s_szErr[32];
            RTStrPrintf(s_szErr, sizeof(s_szErr), "%#x (%d)", dwErr, dwErr);
            return s_szErr;
        }
    }
}

#if 0 /* hacking */
static RTEXITCODE addToStore(const char *pszFilename, PCRTUTF16 pwszStore)
{
    /*
     * Open the source.
     */
    void   *pvFile;
    size_t  cbFile;
    int rc = RTFileReadAll(pszFilename, &pvFile, &cbFile);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTFileReadAll failed on '%s': %Rrc", pszFilename, rc);

    RTEXITCODE rcExit = RTEXITCODE_FAILURE;

    PCCERT_CONTEXT pCertCtx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                                           (PBYTE)pvFile,
                                                           (DWORD)cbFile);
    if (pCertCtx)
    {
        /*
         * Open the destination.
         */
        HCERTSTORE hDstStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
                                             PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
                                             NULL /* hCryptProv = default */,
                                             /*CERT_SYSTEM_STORE_LOCAL_MACHINE*/ CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG,
                                             pwszStore);
        if (hDstStore != NULL)
        {
#if 0
            DWORD dwContextType;
            if (CertAddSerializedElementToStore(hDstStore,
                                                pCertCtx->pbCertEncoded,
                                                pCertCtx->cbCertEncoded,
                                                CERT_STORE_ADD_NEW,
                                                0 /* dwFlags (reserved) */,
                                                CERT_STORE_ALL_CONTEXT_FLAG,
                                                &dwContextType,
                                                NULL))
            {
                RTMsgInfo("Successfully added '%s' to the '%ls' store (ctx type %u)", pszFilename, pwszStore, dwContextType);
                rcExit = RTEXITCODE_SUCCESS;
            }
            else
                RTMsgError("CertAddSerializedElementToStore returned %s", errorToString(GetLastError()));
#else
            if (CertAddCertificateContextToStore(hDstStore, pCertCtx, CERT_STORE_ADD_NEW, NULL))
            {
                RTMsgInfo("Successfully added '%s' to the '%ls' store", pszFilename, pwszStore);
                rcExit = RTEXITCODE_SUCCESS;
            }
            else
                RTMsgError("CertAddCertificateContextToStore returned %s", errorToString(GetLastError()));
#endif

            CertCloseStore(hDstStore, CERT_CLOSE_STORE_CHECK_FLAG);
        }
        else
            RTMsgError("CertOpenStore returned %s", errorToString(GetLastError()));
        CertFreeCertificateContext(pCertCtx);
    }
    else
        RTMsgError("CertCreateCertificateContext returned %s", errorToString(GetLastError()));
    RTFileReadAllFree(pvFile, cbFile);
    return rcExit;

#if 0

    CRYPT_DATA_BLOB Blob;
    Blob.cbData = (DWORD)cbData;
    Blob.pbData = (PBYTE)pvData;
    HCERTSTORE hSrcStore = PFXImportCertStore(&Blob, L"", )

#endif
}
RTDECL(int) RTCrPemReadFile(const char *pszFilename, uint32_t fFlags, PCRTCRPEMMARKER paMarkers, size_t cMarkers,
                            PCRTCRPEMSECTION *ppSectionHead, PRTERRINFO pErrInfo)
{
    AssertReturn(!fFlags, VERR_INVALID_FLAGS);

    size_t      cbContent;
    uint8_t    *pbContent;
    int rc = RTFileReadAllEx(pszFilename, 0, 64U*_1M, RTFILE_RDALL_O_DENY_WRITE, (void **)&pbContent, &cbContent);
    if (RT_SUCCESS(rc))
    {
        PRTCRPEMSECTION pSection = (PRTCRPEMSECTION)RTMemAllocZ(sizeof(*pSection));
        if (pSection)
        {
            /*
             * Try locate the first section.
             */
            size_t          offBegin, offEnd, offResume;
            PCRTCRPEMMARKER pMatch;
            if (   !rtCrPemIsBinaryFile(pbContent, cbContent)
                && rtCrPemFindMarkerSection(pbContent, cbContent, 0 /*offStart*/, paMarkers, cMarkers,
                                            &pMatch, &offBegin, &offEnd, &offResume) )
            {
                PCRTCRPEMSECTION *ppNext = ppSectionHead;
                for (;;)
                {
                    //pSection->pNext         = NULL;
                    pSection->pMarker           = pMatch;
                    //pSection->pbData        = NULL;
                    //pSection->cbData        = 0;
                    //pSection->pszPreamble   = NULL;
                    //pSection->cchPreamble   = 0;

                    *ppNext = pSection;
                    ppNext = &pSection->pNext;

                    /* Decode the section. */
                    /** @todo copy the preamble as well. */
                    rc = rtCrPemDecodeBase64(pbContent + offBegin, offEnd - offBegin,
                                             (void **)&pSection->pbData, &pSection->cbData);
                    if (RT_FAILURE(rc))
                    {
                        pSection->pbData = NULL;
                        pSection->cbData = 0;
                        break;
                    }

                    /* More sections? */
                    if (   offResume + 12 >= cbContent
                        || offResume      >= cbContent
                        || !rtCrPemFindMarkerSection(pbContent, cbContent, offResume, paMarkers, cMarkers,
                                                     &pMatch, &offBegin, &offEnd, &offResume) )
                        break; /* No. */

                    /* Ok, allocate a new record for it. */
                    pSection = (PRTCRPEMSECTION)RTMemAllocZ(sizeof(*pSection));
                    if (RT_UNLIKELY(!pSection))
                    {
                        rc = VERR_NO_MEMORY;
                        break;
                    }
                }
                if (RT_SUCCESS(rc))
                {
                    RTFileReadAllFree(pbContent, cbContent);
                    return rc;
                }

                RTCrPemFreeSections(*ppSectionHead);
            }
            else
            {
                /*
                 * No PEM section found.  Return the whole file as one binary section.
                 */
                //pSection->pNext         = NULL;
                //pSection->pMarker       = NULL;
                pSection->pbData        = pbContent;
                pSection->cbData        = cbContent;
                //pSection->pszPreamble   = NULL;
                //pSection->cchPreamble   = 0;
                *ppSectionHead = pSection;
                return VINF_SUCCESS;
            }
        }
        else
            rc = VERR_NO_MEMORY;
        RTFileReadAllFree(pbContent, cbContent);
    }
    *ppSectionHead = NULL;
    return rc;
}