VirtualBox

Changeset 45339 in vbox


Ignore:
Timestamp:
Apr 4, 2013 2:54:50 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
84750
Message:

Runtime/http: check the digest of the downloaded certificates

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/http.h

    r45331 r45339  
    109109/** @} */
    110110
     111
     112/**
     113 * Determine the digest (fingerprint) of a certificate. Allocate memory for
     114 * storing the SHA1 fingerprint as well as the SHA512 fingerprint. This
     115 * memory has to be freed by RTMemFree().
     116 *
     117 * @todo Move this function to somewhere else.
     118 *
     119 * @returns iprt status code.
     120 *
     121 * @param    hHttp         HTTP interface handle (ignored).
     122 * @param    pcszCert      The certificate in PEM format.
     123 * @param    cbCert        Size of the certificate.
     124 * @param    pabSha1       Where to store the pointer to the SHA1 fingerprint.
     125 * @param    pcbSha1       Where to store the size of the SHA1 fingerprint.
     126 * @param    pabSha512     Where to store the pointer to the SHA512 fingerprint.
     127 * @param    pcbSha512     Where to store the size of the SHA512 fingerprint.
     128 */
     129RTR3DECL(int) RTHttpCertDigest(RTHTTP hHttp, char *pcszCert, size_t cbCert,
     130                               uint8_t **pabSha1, size_t *pcbSha1,
     131                               uint8_t **pabSha512, size_t *pcbSha512);
     132
    111133RT_C_DECLS_END
    112134
  • trunk/src/VBox/Runtime/common/misc/http.cpp

    r45331 r45339  
    3737
    3838#include <curl/curl.h>
     39#include <openssl/ssl.h>
    3940#include "internal/magics.h"
    4041
     
    195196    if (CURL_FAILED(rcCurl))
    196197        return VERR_INVALID_PARAMETER;
     198
     199    return VINF_SUCCESS;
     200}
     201
     202RTR3DECL(int) RTHttpCertDigest(RTHTTP hHttp, char *pcszCert, size_t cbCert,
     203                               uint8_t **pabSha1,   size_t *pcbSha1,
     204                               uint8_t **pabSha512, size_t *pcbSha512)
     205{
     206    BIO *cert = BIO_new_mem_buf(pcszCert, cbCert);
     207    if (!cert)
     208        return VERR_INTERNAL_ERROR;
     209
     210    X509 *crt = NULL;
     211    if (!PEM_read_bio_X509(cert, &crt, NULL, NULL))
     212        return VERR_INTERNAL_ERROR;
     213
     214    unsigned cb;
     215    unsigned char md[EVP_MAX_MD_SIZE];
     216
     217    const EVP_MD *digest = EVP_sha1();
     218    int rc = X509_digest(crt, digest, md, &cb);
     219    if (rc <= 0)
     220        return VERR_INTERNAL_ERROR;
     221    *pabSha1 = (uint8_t*)RTMemAlloc(cb);
     222    if (!*pabSha1)
     223        return VERR_NO_MEMORY;
     224    memcpy(*pabSha1, md, cb);
     225    *pcbSha1 = cb;
     226
     227    digest = EVP_sha512();
     228    rc = X509_digest(crt, digest, md, &cb);
     229    if (rc <= 0)
     230    {
     231        RTMemFree(*pabSha1);
     232        return VERR_INTERNAL_ERROR;
     233    }
     234    *pabSha512 = (uint8_t*)RTMemAlloc(cb);
     235    if (!*pabSha512)
     236    {
     237        RTMemFree(*pabSha512);
     238        return VERR_NO_MEMORY;
     239    }
     240    memcpy(*pabSha512, md, cb);
     241    *pcbSha512 = cb;
    197242
    198243    return VINF_SUCCESS;
  • trunk/src/VBox/Runtime/testcase/tstHttp.cpp

    r45331 r45339  
    6060    if (RT_SUCCESS(rc) && pszBuf)
    6161    {
    62         /// @todo check certificate fingerprint against a strong hash,
    63         // otherwise there's a simple way for a man-in-the-middle attack
    64         rc = RTStrmWrite(CAFile, pszBuf, strlen(pszBuf));
    65         if (RT_SUCCESS(rc))
    66             rc = RTStrmWrite(CAFile, RTFILE_LINEFEED, strlen(RTFILE_LINEFEED));
     62        uint8_t *abSha1;
     63        size_t  cbSha1;
     64        uint8_t *abSha512;
     65        size_t  cbSha512;
     66        const uint8_t abSha1PCA3G5[] =
     67        {
     68            0x4e, 0xb6, 0xd5, 0x78, 0x49, 0x9b, 0x1c, 0xcf, 0x5f, 0x58,
     69            0x1e, 0xad, 0x56, 0xbe, 0x3d, 0x9b, 0x67, 0x44, 0xa5, 0xe5
     70        };
     71        const uint8_t abSha512PCA3G5[] =
     72        {
     73            0xd4, 0xf8, 0x10, 0x54, 0x72, 0x77, 0x0a, 0x2d,
     74            0xe3, 0x17, 0xb3, 0xcf, 0xed, 0x61, 0xae, 0x5c,
     75            0x5d, 0x3e, 0xde, 0xa1, 0x41, 0x35, 0xb2, 0xdf,
     76            0x60, 0xe2, 0x61, 0xfe, 0x3a, 0xc1, 0x66, 0xa3,
     77            0x3c, 0x88, 0x54, 0x04, 0x4f, 0x1d, 0x13, 0x46,
     78            0xe3, 0x8c, 0x06, 0x92, 0x9d, 0x70, 0x54, 0xc3,
     79            0x44, 0xeb, 0x2c, 0x74, 0x25, 0x9e, 0x5d, 0xfb,
     80            0xd2, 0x6b, 0xa8, 0x9a, 0xf0, 0xb3, 0x6a, 0x01
     81        };
     82        rc = RTHttpCertDigest(hHttp, pszBuf, strlen(pszBuf),
     83                              &abSha1, &cbSha1, &abSha512, &cbSha512);
     84        if (RT_SUCCESS(rc))
     85        {
     86            if (cbSha1 != sizeof(abSha1PCA3G5))
     87            {
     88                RTPrintf("Wrong SHA1 digest size of PCA-3G5\n");
     89                rc = VERR_INTERNAL_ERROR;
     90            }
     91            else if (memcmp(abSha1PCA3G5, abSha1, cbSha1))
     92            {
     93                RTPrintf("Wrong SHA1 digest for PCA-3G5:\n"
     94                        "Got:      %.*Rhxs\n"
     95                        "Expected: %.*Rhxs\n",
     96                        cbSha1, abSha1, sizeof(abSha1PCA3G5), abSha1PCA3G5);
     97                rc = VERR_INTERNAL_ERROR;
     98            }
     99            if (cbSha512 != sizeof(abSha512PCA3G5))
     100            {
     101                RTPrintf("Wrong SHA512 digest size of PCA-3G5\n");
     102                rc = VERR_INTERNAL_ERROR;
     103            }
     104            else if (memcmp(abSha512PCA3G5, abSha512, cbSha512))
     105            {
     106                RTPrintf("Wrong SHA512 digest for PCA-3G5:\n"
     107                        "Got:      %.*Rhxs\n"
     108                        "Expected: %.*Rhxs\n",
     109                        cbSha512, abSha512, sizeof(abSha512PCA3G5), abSha512PCA3G5);
     110                rc = VERR_INTERNAL_ERROR;
     111            }
     112            RTMemFree(abSha1);
     113            RTMemFree(abSha512);
     114            if (RT_SUCCESS(rc))
     115                rc = RTStrmWrite(CAFile, pszBuf, strlen(pszBuf));
     116            if (RT_SUCCESS(rc))
     117                rc = RTStrmWrite(CAFile, RTFILE_LINEFEED, strlen(RTFILE_LINEFEED));
     118        }
    67119    }
    68120    if (pszBuf)
     
    79131    if (RT_SUCCESS(rc) && pszBuf)
    80132    {
    81         /// @todo check certificate fingerprint against a strong hash,
    82         // otherwise there's a simple way for a man-in-the-middle attack
    83         rc = RTStrmWrite(CAFile, pszBuf, strlen(pszBuf));
    84         if (RT_SUCCESS(rc))
    85             rc = RTStrmWrite(CAFile, RTFILE_LINEFEED, strlen(RTFILE_LINEFEED));
     133        uint8_t *abSha1;
     134        size_t  cbSha1;
     135        uint8_t *abSha512;
     136        size_t  cbSha512;
     137        const uint8_t abSha1PCA3[] =
     138        {
     139            0xa1, 0xdb, 0x63, 0x93, 0x91, 0x6f, 0x17, 0xe4, 0x18, 0x55,
     140            0x09, 0x40, 0x04, 0x15, 0xc7, 0x02, 0x40, 0xb0, 0xae, 0x6b
     141        };
     142        const uint8_t abSha512PCA3[] =
     143        {
     144            0xbb, 0xf7, 0x8a, 0x19, 0x9f, 0x37, 0xee, 0xa2,
     145            0xce, 0xc8, 0xaf, 0xe3, 0xd6, 0x22, 0x54, 0x20,
     146            0x74, 0x67, 0x6e, 0xa5, 0x19, 0xb7, 0x62, 0x1e,
     147            0xc1, 0x2f, 0xd5, 0x08, 0xf4, 0x64, 0xc4, 0xc6,
     148            0xbb, 0xc2, 0xf2, 0x35, 0xe7, 0xbe, 0x32, 0x0b,
     149            0xde, 0xb2, 0xfc, 0x44, 0x92, 0x5b, 0x8b, 0x9b,
     150            0x77, 0xa5, 0x40, 0x22, 0x18, 0x12, 0xcb, 0x3d,
     151            0x0a, 0x67, 0x83, 0x87, 0xc5, 0x45, 0xc4, 0x99
     152        };
     153        rc = RTHttpCertDigest(hHttp, pszBuf, strlen(pszBuf),
     154                              &abSha1, &cbSha1, &abSha512, &cbSha512);
     155        if (RT_SUCCESS(rc))
     156        {
     157            if (cbSha1 != sizeof(abSha1PCA3))
     158            {
     159                RTPrintf("Wrong SHA1 digest size of PCA-3\n");
     160                rc = VERR_INTERNAL_ERROR;
     161            }
     162            else if (memcmp(abSha1PCA3, abSha1, cbSha1))
     163            {
     164                RTPrintf("Wrong SHA1 digest for PCA-3:\n"
     165                        "Got:      %.*Rhxs\n"
     166                        "Expected: %.*Rhxs\n",
     167                        cbSha1, abSha1, sizeof(abSha1PCA3), abSha1PCA3);
     168                rc = VERR_INTERNAL_ERROR;
     169            }
     170            if (cbSha512 != sizeof(abSha512PCA3))
     171            {
     172                RTPrintf("Wrong SHA512 digest size of PCA-3\n");
     173                rc = VERR_INTERNAL_ERROR;
     174            }
     175            else if (memcmp(abSha512PCA3, abSha512, cbSha512))
     176            {
     177                RTPrintf("Wrong SHA512 digest for PCA-3:\n"
     178                        "Got:      %.*Rhxs\n"
     179                        "Expected: %.*Rhxs\n",
     180                        cbSha512, abSha512, sizeof(abSha512PCA3), abSha512PCA3);
     181                rc = VERR_INTERNAL_ERROR;
     182            }
     183            RTMemFree(abSha1);
     184            RTMemFree(abSha512);
     185            if (RT_SUCCESS(rc))
     186                rc = RTStrmWrite(CAFile, pszBuf, strlen(pszBuf));
     187            if (RT_SUCCESS(rc))
     188                rc = RTStrmWrite(CAFile, RTFILE_LINEFEED, strlen(RTFILE_LINEFEED));
     189        }
    86190    }
    87191    if (pszBuf)
     
    100204    if (RT_SUCCESS(rc))
    101205        rc = RTHttpSetCAFile(hHttp, CAFILE_NAME);
     206
    102207    if (RT_SUCCESS(rc))
    103208        rc = RTHttpGet(hHttp,
     
    109214        cErrors++;
    110215
    111     RTPrintf("Error code: %Rrc\nGot: %s\n", rc, pszBuf);
     216    if (RT_FAILURE(rc))
     217        RTPrintf("Error code: %Rrc\n", rc);
     218    else
     219        RTPrintf("Success!\n");
     220    RTPrintf("Got: %s\n", pszBuf);
    112221    RTMemFree(pszBuf);
    113222
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