⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ocsp.c

📁 ipsec vpn
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (sigdata.ptr == NULL)	return empty_chunk;    /* include our certificate */    pos = build_asn1_explicit_object(&certs, ASN1_CONTEXT_C_0	    , ASN1_SEQUENCE, ocsp_requestor_cert->certificate.len);    chunkcpy(pos, ocsp_requestor_cert->certificate);    /* build signature comprising algorithm, signature and cert */    pos = build_asn1_explicit_object(&signature, ASN1_CONTEXT_C_0	    , ASN1_SEQUENCE	    , sizeof(ASN1_sha1WithRSA_id) + sigdata.len + certs.len);    constcpy( pos, ASN1_sha1WithRSA_id);    mv_chunk(&pos, sigdata);    mv_chunk(&pos, certs);    return signature;}/* * build requestCert (into Request) */static chunk_tbuild_req_cert(ocsp_location_t *location, ocsp_certinfo_t *certinfo){    chunk_t reqCert;    chunk_t issuerNameHash, issuerKeyHash, serialNumber;    u_char *pos;    /* build content */    /* issuer_name_hash */    pos = build_asn1_object(&issuerNameHash, ASN1_OCTET_STRING	    , location->authNameID.len);    chunkcpy(pos, location->authNameID);    /* issuer_key_hash */    pos = build_asn1_object(&issuerKeyHash, ASN1_OCTET_STRING	    , location->authKeyID.len);    chunkcpy(pos, location->authKeyID);    /* serial number */    pos = build_asn1_object(&serialNumber, ASN1_INTEGER	    , certinfo->serialNumber.len);    chunkcpy(pos, certinfo->serialNumber);    /* assembly */    pos = build_asn1_object(&reqCert, ASN1_SEQUENCE	    , sizeof(ASN1_sha1_id) + issuerNameHash.len + issuerKeyHash.len	    + serialNumber.len);    constcpy( pos,  ASN1_sha1_id);    mv_chunk(&pos, issuerNameHash);    mv_chunk(&pos, issuerKeyHash);    mv_chunk(&pos, serialNumber);    return reqCert;}/* * build request (into requestList) */static chunk_tbuild_request(ocsp_location_t *location, ocsp_certinfo_t *certinfo){    /* build request - no singleRequestExtensions used */    chunk_t request, reqCert;    u_char *pos;    /* build content */    reqCert = build_req_cert(location, certinfo);    pos = build_asn1_object(&request, ASN1_SEQUENCE	    , reqCert.len);    mv_chunk(&pos, reqCert);    return request;}/* * build requestList (into TBSRequest) */static chunk_tbuild_request_list(ocsp_location_t *location){    chunk_t requestList;    request_list_t *reqs = NULL;    ocsp_certinfo_t *certinfo = location->certinfo;    u_char *pos;    size_t datalen = 0;    /* build content */    while (certinfo != NULL)    {	/* build request for every certificate in list	 * and store them in a chained list	 */	request_list_t *req = alloc_thing(request_list_t, "ocsp request");	req->request = build_request(location, certinfo);	req->next = reqs;	reqs = req;	datalen += req->request.len;	certinfo = certinfo->next;    }    pos = build_asn1_object(&requestList, ASN1_SEQUENCE	    , datalen);    /* copy all in chained list, free list afterwards */    while (reqs != NULL)    { 	request_list_t *req = reqs;	mv_chunk(&pos, req->request);	reqs = reqs->next;	pfree(req);    }    return requestList;}/* * build requestorName (into TBSRequest) */static chunk_tbuild_requestor_name(void){    chunk_t reqName;    u_char *pos;    pos = build_asn1_explicit_object(&reqName, ASN1_CONTEXT_C_1	    , ASN1_CONTEXT_C_4, ocsp_requestor_cert->subject.len);    chunkcpy(pos, ocsp_requestor_cert->subject);    return reqName;}/* * build nonce extension (into requestExtensions) */static chunk_tbuild_nonce_extension(ocsp_location_t *location){    chunk_t nonce, content;    u_char *pos;    /* generate a random nonce */    pos = build_asn1_object(&content, ASN1_OCTET_STRING	    , NONCE_LENGTH);    get_rnd_bytes(pos, NONCE_LENGTH);    clonetochunk(location->nonce, pos, NONCE_LENGTH, "ocsp nonce");    pos = build_asn1_object(&nonce, ASN1_SEQUENCE	    , sizeof(ASN1_nonce_oid) + content.len);    constcpy( pos, ASN1_nonce_oid);    mv_chunk(&pos, content);    return nonce;}/* * build acceptable response types extension (into requestExtensions) */static chunk_tbuild_accept_extension(void){    chunk_t acceptExt, content;    u_char *pos;    /* content is a sequence of OIDs in an octet string     * in our case only BasicOCSPResponse     */    clonetochunk(content, ASN1_response_content, sizeof(ASN1_response_content)	, "clone");    pos = build_asn1_object(&acceptExt, ASN1_SEQUENCE	    , sizeof(ASN1_response_oid) + content.len);    constcpy( pos, ASN1_response_oid);    mv_chunk(&pos, content);    return acceptExt;}/* * build requestExtensions (into TBSRequest) */static chunk_tbuild_request_ext(ocsp_location_t *location){    chunk_t requestExt;    chunk_t nonceExt, acceptTypes;    u_char *pos;    /* build content */    nonceExt = build_nonce_extension(location);    acceptTypes = build_accept_extension();    pos = build_asn1_explicit_object(&requestExt, ASN1_CONTEXT_C_2	    , ASN1_SEQUENCE, nonceExt.len + acceptTypes.len);    mv_chunk(&pos, nonceExt);    mv_chunk(&pos, acceptTypes);    return requestExt;}/* * build TBSRequest (into OCSPRequest) */static chunk_tbuild_tbs_request(ocsp_location_t *location, bool has_requestor_cert){    chunk_t tbsRequest;    chunk_t requestList, requestorName, requestExt;    u_char *pos;    /* build content */    /* version is skipped since the default is ok */    requestorName = (has_requestor_cert)? build_requestor_name()					: empty_chunk;    requestList = build_request_list(location);    requestExt = build_request_ext(location);    pos = build_asn1_object(&tbsRequest, ASN1_SEQUENCE	    , requestList.len + requestorName.len + requestExt.len);    mv_chunk(&pos, requestorName);    mv_chunk(&pos, requestList);    mv_chunk(&pos, requestExt);    return tbsRequest;}/* assembles an ocsp request to given location * and sets nonce field in location to the sent nonce */chunk_tbuild_ocsp_request(ocsp_location_t *location){    bool has_requestor_cert;    chunk_t request, tbsRequest, signature;    char buf[BUF_LEN];    u_char *pos;    DBG(DBG_CONTROL,	DBG_log("assembling ocsp request");	dntoa(buf, BUF_LEN, location->issuer);	DBG_log("issuer: '%s'", buf);	if (location->authKeyID.ptr != NULL)	{	    datatot(location->authKeyID.ptr, location->authKeyID.len, ':'		, buf, BUF_LEN);	    DBG_log("authkey: %s", buf);	}    )    lock_certs_and_keys("build_ocsp_request");    /* looks for requestor cert and matching private key */    has_requestor_cert = get_ocsp_requestor_cert(location);    /* build content */    tbsRequest = build_tbs_request(location, has_requestor_cert);    /* sign tbsReuqest */    signature = (has_requestor_cert)? build_signature(tbsRequest)				    : empty_chunk;    unlock_certs_and_keys("build_ocsp_request");    /* build ocsp request */    pos = build_asn1_object(&request, ASN1_SEQUENCE	    , tbsRequest.len + signature.len);    mv_chunk(&pos, tbsRequest);    mv_chunk(&pos, signature);    return request;}/* * check if the OCSP response has a valid signature */static boolvalid_ocsp_response(response_t *res){    int pathlen;    x509cert_t *authcert;    lock_authcert_list("valid_ocsp_response");        authcert = get_authcert(res->responder_id_name, empty_chunk		    , res->responder_id_key, AUTH_OCSP | AUTH_CA);    if (authcert == NULL)    {	plog("no matching ocsp signer cert found");	unlock_authcert_list("valid_ocsp_response");	return FALSE;    }    DBG(DBG_CONTROL,	DBG_log("ocsp signer cert found")    )    if (!check_signature(res->tbs, res->signature,			 res->algorithm, authcert))    {	plog("signature of ocsp response is invalid");	unlock_authcert_list("valid_ocsp_response");	return FALSE;    }    DBG(DBG_CONTROL,	DBG_log("signature of ocsp response is valid")    )    for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)    {	u_char buf[BUF_LEN];	err_t ugh = NULL;	time_t until;	x509cert_t *cert = authcert;	DBG(DBG_CONTROL,	    dntoa(buf, BUF_LEN, cert->subject);	    DBG_log("subject: '%s'",buf);	    dntoa(buf, BUF_LEN, cert->issuer);	    DBG_log("issuer:  '%s'",buf);	    if (cert->authKeyID.ptr != NULL)	    {		datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'		    , buf, BUF_LEN);		DBG_log("authkey:  %s", buf);	    }	)	ugh = check_validity(authcert, &until);	if (ugh != NULL)	{	    plog("%s", ugh);	    unlock_authcert_list("valid_ocsp_response");	    return FALSE;        }		DBG(DBG_CONTROL,	    DBG_log("certificate is valid")	)		authcert = get_authcert(cert->issuer, cert->authKeySerialNumber	    , cert->authKeyID, AUTH_CA);	if (authcert == NULL)	{	    plog("issuer cacert not found");	    unlock_authcert_list("valid_ocsp_response");	    return FALSE;	}	DBG(DBG_CONTROL,	    DBG_log("issuer cacert found")	)	if (!check_signature(cert->tbsCertificate, cert->signature,			     cert->algorithm, authcert))	{	    plog("certificate signature is invalid");	    unlock_authcert_list("valid_ocsp_response");	    return FALSE;	}	DBG(DBG_CONTROL,	    DBG_log("certificate signature is valid")	)	/* check if cert is self-signed */	if (same_dn(cert->issuer, cert->subject))	{	    DBG(DBG_CONTROL,		DBG_log("reached self-signed root ca")	    )	    unlock_authcert_list("valid_ocsp_response");            return TRUE;	}    }    plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);    unlock_authcert_list("valid_ocsp_response");    return FALSE;}/* * parse a basic OCSP response */static boolparse_basic_ocsp_response(chunk_t blob, int level0, response_t *res){    u_int level, version, extn_oid = 0;    u_char buf[BUF_LEN];    asn1_ctx_t ctx;    bool critical;    chunk_t object;    int objectID = 0;    asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);    while (objectID < BASIC_RESPONSE_ROOF)    {	if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))	    return FALSE;		switch (objectID)	{	case BASIC_RESPONSE_TBS_DATA:	    res->tbs = object;	    break;	case BASIC_RESPONSE_VERSION:	    version = (object.len)? (1 + (u_int)*object.ptr) : 1;	    if (version != OCSP_BASIC_RESPONSE_VERSION)	    {		plog("wrong ocsp basic response version (version= %i)",  version);		return FALSE;	    }	    break;	case BASIC_RESPONSE_ID_BY_NAME:	    res->responder_id_name = object;	    DBG(DBG_PARSING,		dntoa(buf, BUF_LEN, object);		DBG_log("  '%s'",buf)	    )	    break;	case BASIC_RESPONSE_ID_BY_KEY:	    res->responder_id_key = object;	    break;	case BASIC_RESPONSE_PRODUCED_AT:	    res->produced_at = asn1totime(&object, ASN1_GENERALIZEDTIME);	    break;	case BASIC_RESPONSE_RESPONSES:	    res->responses = object;	    break;	case BASIC_RESPONSE_EXT_ID:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -