예제 #1
0
int SslOcspStapling::getCertId(X509 *pCert)
{
    int     i, n;
    X509                *pXissuer;
    X509_STORE          *pXstore;
    STACK_OF(X509)      *pXchain;
    X509_STORE_CTX      *pXstore_ctx;


    pXchain = m_pCtx->extra_certs;
    n = sk_X509_num(pXchain);
    for (i = 0; i < n; i++)
    {
        pXissuer = sk_X509_value(pXchain, i);
        if (X509_check_issued(pXissuer, pCert) == X509_V_OK)
        {
            CRYPTO_add(&pXissuer->references, 1, CRYPTO_LOCK_X509);
            m_pCertId = OCSP_cert_to_id(NULL, pCert, pXissuer);
            X509_free(pXissuer);
            return 0;
        }
    }
    pXstore = SSL_CTX_get_cert_store(m_pCtx);
    if (pXstore == NULL)
    {
        setLastErrMsg("SSL_CTX_get_cert_store failed!\n");
        return LS_FAIL;
    }
    pXstore_ctx = X509_STORE_CTX_new();
    if (pXstore_ctx == NULL)
    {
        setLastErrMsg("X509_STORE_CTX_new failed!\n");
        return LS_FAIL;
    }
    if (X509_STORE_CTX_init(pXstore_ctx, pXstore, NULL, NULL) == 0)
    {
        setLastErrMsg("X509_STORE_CTX_init failed!\n");
        return LS_FAIL;
    }
    n = X509_STORE_CTX_get1_issuer(&pXissuer, pXstore_ctx, pCert);
    X509_STORE_CTX_free(pXstore_ctx);
    if ((n == -1) || (n == 0))
    {
        setLastErrMsg("X509_STORE_CTX_get1_issuer failed!\n");
        return LS_FAIL;
    }
    m_pCertId = OCSP_cert_to_id(NULL, pCert, pXissuer);
    X509_free(pXissuer);
    return 0;
}
예제 #2
0
int SslOcspStapling::init(SSL_CTX *pSslCtx)
{
    int             iResult;
    X509           *pCert;
    struct stat     st;
    m_pCtx = pSslCtx;
    pCert = NULL;
    iResult = -1;

    if (::stat(m_sRespfileTmp.c_str(), &st) == 0)
    {
        if ((st.st_mtime + 30) <= time(NULL))
            unlink(m_sRespfileTmp.c_str());
    }
    //SSL_CTX_set_default_verify_paths( m_pCtx );

    pCert = load_cert(m_sCertfile.c_str());
    if (pCert == NULL)
    {
        setLastErrMsg("Failed to load file: %s!\n", m_sCertfile.c_str());
        return LS_FAIL;
    }

    if ((getCertId(pCert) == 0) && (getResponder(pCert) == 0))
    {
        m_addrResponder.setHttpUrl(m_sOcspResponder.c_str(),
                                   m_sOcspResponder.len());
        iResult = 0;
        //update();

    }
    X509_free(pCert);
    return iResult;
}
예제 #3
0
int SslOcspStapling::certVerify(OCSP_RESPONSE *pResponse,
                                OCSP_BASICRESP *pBasicResp, X509_STORE *pXstore)
{
    int                 n, iResult = -1;
    STACK_OF(X509)      *pXchain;
    ASN1_GENERALIZEDTIME  *pThisupdate, *pNextupdate;
    struct stat         st;

    pXchain = m_pCtx->extra_certs;
    if (OCSP_basic_verify(pBasicResp, pXchain, pXstore, OCSP_NOVERIFY) == 1)
    {
        if ((m_pCertId != NULL)
            && (OCSP_resp_find_status(pBasicResp, m_pCertId, &n,
                                      NULL, NULL, &pThisupdate, &pNextupdate) == 1)
            && (n == V_OCSP_CERTSTATUS_GOOD)
            && (OCSP_check_validity(pThisupdate, pNextupdate, 300, -1) == 1))
        {
            iResult = 0;
            updateRespData(pResponse);
            unlink(m_sRespfile.c_str());
            rename(m_sRespfileTmp.c_str(), m_sRespfile.c_str());
            if (::stat(m_sRespfile.c_str(), &st) == 0)
                m_RespTime = st.st_mtime;
        }
    }
    if (iResult)
    {
        setLastErrMsg("%s", SSLError().what());
        ERR_clear_error();
        if (m_pHttpFetch)
            m_pHttpFetch->writeLog(s_ErrMsg.c_str());

    }
    return iResult;
}
예제 #4
0
int SslOcspStapling::createRequest()
{
    int             len, len64, n1;
    unsigned char   *pReqData, *pReqData64;
    unsigned char   ReqData[4000], ReqData64[4000];
    struct stat     st;
    if (::stat(m_sRespfileTmp.c_str(), &st) == 0)
        return 0;
    pReqData = ReqData;
    pReqData64 = ReqData64;
    len = getRequestData(pReqData);
    if (len <= 0)
        return LS_FAIL;
    len64 = ls_base64_encode((const char *)ReqData, len, (char *)pReqData64);

    const char *pUrl = m_sOcspResponder.c_str();
    memcpy(pReqData,  pUrl, m_sOcspResponder.len());

    pReqData += m_sOcspResponder.len();
    if (pUrl[m_sOcspResponder.len() - 1] != '/')
        *pReqData++ = '/';

    n1 = escapeBase64Uri(pReqData64, len64, pReqData);
    pReqData += n1;
    *pReqData = 0;
    len = pReqData - ReqData;

    if (m_pHttpFetch != NULL)
        delete m_pHttpFetch;
    m_pHttpFetch = new HttpFetch();
    m_pHttpFetch->setResProcessor(OcspRespCb, this);
    m_pHttpFetch->setTimeout(30);  //Set Req timeout as 30 seconds
    m_pHttpFetch->startReq((const char *)ReqData, 1, 1, NULL, 0,
                           m_sRespfileTmp.c_str(), NULL, m_addrResponder);
    setLastErrMsg("%lu, len = %d\n%s \n", m_pHttpFetch, len, ReqData);
    //printf("%s\n", s_ErrMsg.c_str());
    return 0;
}
예제 #5
0
int SslOcspStapling::processResponse(HttpFetch *pHttpFetch)
{
    struct stat        st;
    const char          *pRespContentType;
    //assert( pHttpFetch == m_pHttpFetch );
    int istatusCode = m_pHttpFetch->getStatusCode() ;
    pRespContentType = m_pHttpFetch->getRespContentType();
    if ((istatusCode == 200)
        && (strcasecmp(pRespContentType, "application/ocsp-response") == 0))
        verifyRespFile();
    else
    {
        setLastErrMsg("Received bad OCSP response. ReponderUrl=%s, StatusCode=%d, ContentType=%s\n",
                      m_sOcspResponder.c_str(), istatusCode,
                      ((pRespContentType) ? (pRespContentType) : ("")));
        //printf("%s\n", s_ErrMsg.c_str());
        m_pHttpFetch->writeLog(s_ErrMsg.c_str());
    }

    if (::stat(m_sRespfileTmp.c_str(), &st) == 0)
        unlink(m_sRespfileTmp.c_str());
    return 0;
}
예제 #6
0
int SslOcspStapling::getResponder(X509 *pCert)
{
    char                    *pUrl;
    X509                    *pCAt;
    STACK_OF(X509)          *pXchain;
    int                     i;
    int                     n;

#if OPENSSL_VERSION_NUMBER >= 0x10000003L
    STACK_OF(OPENSSL_STRING)  *strResp;
#else
    STACK                    *strResp;
#endif
    if (m_sOcspResponder.c_str())
        return 0;
    strResp = X509_get1_ocsp(pCert);
    if (strResp == NULL)
    {
        pXchain = m_pCtx->extra_certs;
        n = sk_X509_num(pXchain);
        for (i = 0; i < n; i++)
        {
            pCert = sk_X509_value(pXchain, i);
            strResp = X509_get1_ocsp(pCert);
            if (strResp)
                break;
        }
    }
    if (strResp == NULL)
    {
        if (m_sCAfile.c_str() == NULL)
            return LS_FAIL;
        pCAt = load_cert(m_sCAfile.c_str());
        if (pCAt == NULL)
        {
            setLastErrMsg("Failed to load file: %s!\n", m_sCAfile.c_str());
            return LS_FAIL;
        }

        strResp = X509_get1_ocsp(pCAt);
        X509_free(pCAt);
        if (strResp == NULL)
        {
            setLastErrMsg("Failed to get responder!\n");
            return LS_FAIL;
        }
    }
#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
    pUrl = sk_OPENSSL_STRING_value(strResp, 0);
#elif OPENSSL_VERSION_NUMBER >= 0x10000003L
    pUrl = (char *)sk_value((const _STACK *) strResp, 0);
#else
    pUrl = (char *)sk_value((const STACK *) strResp, 0);
#endif
    if (pUrl)
    {
        m_sOcspResponder.setStr(pUrl);
        return 0;
    }
    X509_email_free(strResp);
    setLastErrMsg("Failed to get responder Url!\n");
    return LS_FAIL;
}