예제 #1
0
파일: ocsp.c 프로젝트: agnov8/wolfssl
int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert, buffer* responseBuffer)
{
    int ret = OCSP_LOOKUP_FAIL;

#ifdef WOLFSSL_SMALL_STACK
    OcspRequest* ocspRequest;
#else
    OcspRequest ocspRequest[1];
#endif

    WOLFSSL_ENTER("CheckCertOCSP");


#ifdef WOLFSSL_SMALL_STACK
    ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
                                                       DYNAMIC_TYPE_TMP_BUFFER);
    if (ocspRequest == NULL) {
        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
        return MEMORY_E;
    }
#endif

    if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce) == 0) {
        ret = CheckOcspRequest(ocsp, ocspRequest, responseBuffer);

        FreeOcspRequest(ocspRequest);
    }

#ifdef WOLFSSL_SMALL_STACK
    XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    WOLFSSL_LEAVE("CheckCertOCSP", ret);
    return ret;
}
예제 #2
0
int CheckCertOCSP(CYASSL_OCSP* ocsp, DecodedCert* cert)
{
    byte* ocspReqBuf = NULL;
    int ocspReqSz = 2048;
    byte* ocspRespBuf = NULL;
    OcspRequest ocspRequest;
    OcspResponse ocspResponse;
    int result = -1;
    OCSP_Entry* ocspe;
    CertStatus* certStatus = NULL;
    CertStatus newStatus;
    const char *url;
    int urlSz;

    CYASSL_ENTER("CheckCertOCSP");

    if (LockMutex(&ocsp->ocspLock) != 0) {
        CYASSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
        return BAD_MUTEX_E;
    }

    ocspe = ocsp->ocspList;
    while (ocspe) {
        if (XMEMCMP(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0
            && XMEMCMP(ocspe->issuerKeyHash, cert->issuerKeyHash,
                                                        SHA_DIGEST_SIZE) == 0)
            break;
        else
            ocspe = ocspe->next;
    }

    if (ocspe == NULL) {
        ocspe = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry),
                                                NULL, DYNAMIC_TYPE_OCSP_ENTRY);
        if (ocspe != NULL) {
            InitOCSP_Entry(ocspe, cert);
            ocspe->next = ocsp->ocspList;
            ocsp->ocspList = ocspe;
        }
        else {
            UnLockMutex(&ocsp->ocspLock);
            CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
            return MEMORY_ERROR;
        }
    }
    else {
        certStatus = ocspe->status;
        while (certStatus) {
            if (certStatus->serialSz == cert->serialSz &&
                 XMEMCMP(certStatus->serial, cert->serial, cert->serialSz) == 0)
                break;
            else
                certStatus = certStatus->next;
        }
    }

    if (certStatus != NULL) {
        if (!ValidateDate(certStatus->thisDate,
                                        certStatus->thisDateFormat, BEFORE) ||
            (certStatus->nextDate[0] == 0) ||
            !ValidateDate(certStatus->nextDate,
                                        certStatus->nextDateFormat, AFTER)) {
            CYASSL_MSG("\tinvalid status date, looking up cert");
        }
        else {
            result = xstat2err(certStatus->status);
            UnLockMutex(&ocsp->ocspLock);
            CYASSL_LEAVE("CheckCertOCSP", result);
            return result;
        }
    }

    UnLockMutex(&ocsp->ocspLock);

    if (ocsp->cm->ocspUseOverrideURL) {
        url = ocsp->cm->ocspOverrideURL;
        if (url != NULL && url[0] != '\0')
            urlSz = (int)XSTRLEN(url);
        else
            return OCSP_NEED_URL;
    }
    else if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
        url = (const char *)cert->extAuthInfo;
        urlSz = cert->extAuthInfoSz;
    }
    else {
        /* cert doesn't have extAuthInfo, assuming CERT_GOOD */
        return 0;
    }

    ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
    if (ocspReqBuf == NULL) {
        CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
        return MEMORY_ERROR;
    }
    InitOcspRequest(&ocspRequest, cert, ocsp->cm->ocspSendNonce,
                                                         ocspReqBuf, ocspReqSz);
    ocspReqSz = EncodeOcspRequest(&ocspRequest);
    
    if (ocsp->cm->ocspIOCb)
        result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz,
                                           ocspReqBuf, ocspReqSz, &ocspRespBuf);

    if (result >= 0 && ocspRespBuf) {
        XMEMSET(&newStatus, 0, sizeof(CertStatus));

        InitOcspResponse(&ocspResponse, &newStatus, ocspRespBuf, result);
        OcspResponseDecode(&ocspResponse);
    
        if (ocspResponse.responseStatus != OCSP_SUCCESSFUL)
            result = OCSP_LOOKUP_FAIL;
        else {
            if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0) {
                result = xstat2err(ocspResponse.status->status);

                if (LockMutex(&ocsp->ocspLock) != 0)
                    result = BAD_MUTEX_E;
                else {
                    if (certStatus != NULL)
                        /* Replace existing certificate entry with updated */
                        XMEMCPY(certStatus, &newStatus, sizeof(CertStatus));
                    else {
                        /* Save new certificate entry */
                        certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus),
                                          NULL, DYNAMIC_TYPE_OCSP_STATUS);
                        if (certStatus != NULL) {
                            XMEMCPY(certStatus, &newStatus, sizeof(CertStatus));
                            certStatus->next = ocspe->status;
                            ocspe->status = certStatus;
                            ocspe->totalStatus++;
                        }
                    }

                    UnLockMutex(&ocsp->ocspLock);
                }
            }
            else
                result = OCSP_LOOKUP_FAIL;
        }
    }
    else
        result = OCSP_LOOKUP_FAIL;

    if (ocspReqBuf != NULL)
        XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);

    if (ocspRespBuf != NULL && ocsp->cm->ocspRespFreeCb)
        ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, ocspRespBuf);

    CYASSL_LEAVE("CheckCertOCSP", result);
    return result;
}
예제 #3
0
파일: ocsp.c 프로젝트: EvertYing/cyassl
int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
{
    byte* ocspReqBuf = NULL;
    int ocspReqSz = 2048;
    byte* ocspRespBuf = NULL;
    OcspRequest ocspRequest;
    OcspResponse ocspResponse;
    int result = 0;
    OCSP_Entry* ocspe;
    CertStatus* certStatus;
    const char *url;
    int urlSz;

    /* If OCSP lookups are disabled, return success. */
    if (!ocsp->enabled) {
        CYASSL_MSG("OCSP lookup disabled, assuming CERT_GOOD");
        return 0;
    }

    ocspe = find_ocsp_entry(ocsp, cert);
    if (ocspe == NULL) {
        CYASSL_MSG("alloc OCSP entry failed");
        return MEMORY_ERROR;
    }

    certStatus = find_cert_status(ocspe, cert);
    if (certStatus == NULL)
    {
        CYASSL_MSG("alloc OCSP cert status failed");
        return MEMORY_ERROR;
    }

    if (certStatus->status != -1)
    {
        if (!ValidateDate(certStatus->thisDate,
                                        certStatus->thisDateFormat, BEFORE) ||
            (certStatus->nextDate[0] == 0) ||
            !ValidateDate(certStatus->nextDate,
                                        certStatus->nextDateFormat, AFTER))
        {
            CYASSL_MSG("\tinvalid status date, looking up cert");
            certStatus->status = -1;
        }
        else
        {
            CYASSL_MSG("\tusing cached status");
            result = xstat2err(certStatus->status);
            return result;
        }
    }

    if (ocsp->useOverrideUrl) {
        if (ocsp->overrideUrl[0] != '\0') {
            url = ocsp->overrideUrl;
            urlSz = (int)XSTRLEN(url);
        }
        else
            return OCSP_NEED_URL;
    }
    else if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
        url = (const char *)cert->extAuthInfo;
        urlSz = cert->extAuthInfoSz;
    }
    else {
        CYASSL_MSG("\tcert doesn't have extAuthInfo, assuming CERT_GOOD");
        return 0;
    }

    ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
    if (ocspReqBuf == NULL) {
        CYASSL_MSG("\talloc OCSP request buffer failed");
        return MEMORY_ERROR;
    }
    InitOcspRequest(&ocspRequest, cert, ocsp->useNonce, ocspReqBuf, ocspReqSz);
    ocspReqSz = EncodeOcspRequest(&ocspRequest);
    
    if (ocsp->CBIOOcsp) {
        result = ocsp->CBIOOcsp(ocsp->IOCB_OcspCtx, url, urlSz,
                                          ocspReqBuf, ocspReqSz, &ocspRespBuf);
    }

    if (result >= 0 && ocspRespBuf) {
        InitOcspResponse(&ocspResponse, certStatus, ocspRespBuf, result);
        OcspResponseDecode(&ocspResponse);
    
        if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) {
            CYASSL_MSG("OCSP Responder failure");
            result = OCSP_LOOKUP_FAIL;
        } else {
            if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0)
            {
                result = xstat2err(ocspResponse.status->status);
            }
            else
            {
                CYASSL_MSG("OCSP Response incorrect for Request");
                result = OCSP_LOOKUP_FAIL;
            }
        }
    }
    else {
        result = OCSP_LOOKUP_FAIL;
    }

    if (ocspReqBuf != NULL) {
        XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
    }
    if (ocspRespBuf != NULL && ocsp->CBIOOcspRespFree) {
        ocsp->CBIOOcspRespFree(ocsp->IOCB_OcspCtx, ocspRespBuf);
    }

    return result;
}
예제 #4
0
파일: ocsp.c 프로젝트: bohrasd/windowsrtdev
int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
{
    byte ocspReqBuf[SCRATCH_BUFFER_SIZE];
    int ocspReqSz = SCRATCH_BUFFER_SIZE;
    byte* ocspRespBuf = NULL;
    OcspRequest ocspRequest;
    OcspResponse ocspResponse;
    int result = 0;
    OCSP_Entry* ocspe;
    CertStatus* certStatus;

    /* If OCSP lookups are disabled, return success. */
    if (!ocsp->enabled) {
        CYASSL_MSG("OCSP lookup disabled, assuming CERT_GOOD");
        return 0;
    }

    ocspe = find_ocsp_entry(ocsp, cert);
    if (ocspe == NULL) {
        CYASSL_MSG("alloc OCSP entry failed");
        return MEMORY_ERROR;
    }

    certStatus = find_cert_status(ocspe, cert);
    if (certStatus == NULL)
    {
        CYASSL_MSG("alloc OCSP cert status failed");
        return MEMORY_ERROR;
    }

    if (certStatus->status != -1)
    {
        if (!ValidateDate(certStatus->thisDate,
                                        certStatus->thisDateFormat, BEFORE) ||
            (certStatus->nextDate[0] == 0) ||
            !ValidateDate(certStatus->nextDate,
                                        certStatus->nextDateFormat, AFTER))
        {
            CYASSL_MSG("\tinvalid status date, looking up cert");
            certStatus->status = -1;
        }
        else
        {
            CYASSL_MSG("\tusing cached status");
            result = xstat2err(certStatus->status);
            return result;
        }
    }
    
    InitOcspRequest(&ocspRequest, cert, ocspReqBuf, ocspReqSz);
    ocspReqSz = EncodeOcspRequest(&ocspRequest);
    result = http_ocsp_transaction(ocsp, cert,
                                        ocspReqBuf, ocspReqSz, &ocspRespBuf);
    if (result < 0) return result;
        /* If the transaction failed, return that result. */

    InitOcspResponse(&ocspResponse, certStatus, ocspRespBuf, result);
    OcspResponseDecode(&ocspResponse);

    if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) {
        CYASSL_MSG("OCSP Responder failure");
        result = OCSP_LOOKUP_FAIL;
    } else {
        if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0)
        {
            result = xstat2err(ocspResponse.status->status);
        }
        else
        {
            CYASSL_MSG("OCSP Response incorrect for Request");
            result = OCSP_LOOKUP_FAIL;
        }
    }
    if (ocspRespBuf != NULL) {
        XFREE(ocspRespBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
    }

    return result;
}