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

📄 ocsp.c

📁 ipsec vpn
💻 C
📖 第 1 页 / 共 4 页
字号:
#endif        switch (status)    {    case CERT_GOOD:    	DBG(DBG_CONTROL,	    DBG_log("certificate is good")	)	/* with strict crl policy the public key must have the	 * same lifetime as the validity of the ocsp status	 */	if (strict && nextUpdate < *until)	    *until = nextUpdate;	break;    case CERT_REVOKED:	plog("certificate is revoked");	remove_x509_public_key(cert);	return FALSE;    case CERT_UNKNOWN:	plog("certificate status unkown");	if (strict)	{	    remove_x509_public_key(cert);	    return FALSE;	}	break;    }    return TRUE;}/* * check if an ocsp status is about to expire */voidcheck_ocsp(void){    ocsp_location_t *location;    lock_ocsp_cache("check_ocsp");    location = ocsp_cache;        while (location != NULL)    {	char buf[BUF_LEN];	bool first = TRUE;	ocsp_certinfo_t *certinfo = location->certinfo;	while (certinfo != NULL)	{	    if (!certinfo->once)	    {		time_t time_left = certinfo->nextUpdate - time(NULL);		DBG(DBG_CONTROL,		    if (first)		    {			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);			}			first = FALSE;		    }		    datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len			, ':', buf, BUF_LEN);		    DBG_log("serial: %s, %ld seconds left", buf, time_left)		)#ifdef HAVE_THREADS		if (time_left < 2*crl_check_interval)		    add_ocsp_fetch_request(location, certinfo->serialNumber);#endif	    }	    certinfo = certinfo->next;	}	location = location->next;    }    unlock_ocsp_cache("check_ocsp");}/* * sets the default uri */voidocsp_set_default_uri(char *uri){    ocsp_default_uri = empty_chunk;        if (uri == NULL)	return;        if (strncasecmp(uri, "http", 4) != 0)    {	plog("warning: ignoring default ocsp uri with unkown protocol");	return;    }        clonetochunk(ocsp_default_uri, uri, strlen(uri), "ocsp default uri");}/* *  frees the allocated memory of a certinfo struct */static voidfree_certinfo(ocsp_certinfo_t *certinfo){    freeanychunk(certinfo->serialNumber);    pfree(certinfo);}/* * frees all certinfos in a chained list */static voidfree_certinfos(ocsp_certinfo_t *chain){    ocsp_certinfo_t *certinfo;    while (chain != NULL)    {	certinfo = chain;	chain = chain->next;	free_certinfo(certinfo);    }}/* * frees the memory allocated to an ocsp location including all certinfos */static voidfree_ocsp_location(ocsp_location_t* location){    freeanychunk(location->issuer);    freeanychunk(location->authNameID);    freeanychunk(location->authKeyID);    freeanychunk(location->authKeySerialNumber);    freeanychunk(location->uri);    free_certinfos(location->certinfo);    pfree(location);}/* * free a chained list of ocsp locations */voidfree_ocsp_locations(ocsp_location_t **chain){    while (*chain != NULL)    {	ocsp_location_t *location = *chain;	*chain = location->next;	free_ocsp_location(location);    }}/* * free the ocsp cache */voidfree_ocsp_cache(void){    lock_ocsp_cache("free_ocsp_cache");    free_ocsp_locations(&ocsp_cache);    unlock_ocsp_cache("free_ocsp_cache");}/* * frees the ocsp cache and global variables */voidfree_ocsp(void){    pfreeany(ocsp_default_uri.ptr);    free_ocsp_cache();}/* * list a chained list of ocsp_locations */voidlist_ocsp_locations(ocsp_location_t *location, bool requests, bool utc, bool strict){    bool first = TRUE;    while (location != NULL)    {	ocsp_certinfo_t *certinfo = location->certinfo;	if (certinfo != NULL)	{	    u_char buf[BUF_LEN];	    if (first)	    {		whack_log(RC_COMMENT, " ");		whack_log(RC_COMMENT, "List of OCSP %s:", requests?		    "fetch requests":"responses");		first = FALSE;            }	    whack_log(RC_COMMENT, " ");	    if (location->issuer.ptr != NULL)	    {		dntoa(buf, BUF_LEN, location->issuer);		whack_log(RC_COMMENT, "       issuer:  '%s'", buf);	    }	    whack_log(RC_COMMENT, "       uri:     '%.*s", (int)location->uri.len		, location->uri.ptr);	    if (location->authNameID.ptr != NULL)	    {		datatot(location->authNameID.ptr, location->authNameID.len, ':'		    , buf, BUF_LEN);		whack_log(RC_COMMENT, "       authname: %s", buf);	    }	    if (location->authKeyID.ptr != NULL)	    {		datatot(location->authKeyID.ptr, location->authKeyID.len, ':'		    , buf, BUF_LEN);		whack_log(RC_COMMENT, "       authkey:  %s", buf);	    }	    if (location->authKeySerialNumber.ptr != NULL)	    {		datatot(location->authKeySerialNumber.ptr		    , location->authKeySerialNumber.len, ':', buf, BUF_LEN);		whack_log(RC_COMMENT, "       aserial:  %s", buf);	    }	    while (certinfo != NULL)	    {		char thisUpdate[TIMETOA_BUF];				timetoa(&certinfo->thisUpdate, utc, thisUpdate, sizeof(thisUpdate));		if (requests)		{		    whack_log(RC_COMMENT, "%s, trials: %d", thisUpdate			, certinfo->trials);		}		else if (certinfo->once)		{		    whack_log(RC_COMMENT, "%s, onetime use%s", thisUpdate			, (certinfo->nextUpdate < time(NULL))? " (expired)": "");		}		else		{		    char tbuf2[TIMETOA_BUF];		    whack_log(RC_COMMENT, "%s, until %s %s", thisUpdate			      , timetoa(&certinfo->nextUpdate, utc, tbuf2, sizeof(tbuf2))			      , check_expiry(certinfo->nextUpdate, OCSP_WARNING_INTERVAL, strict));		}		datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len, ':'		    , buf, BUF_LEN);		whack_log(RC_COMMENT, "       serial:   %s, %s", buf		    , cert_status_names[certinfo->status]);		certinfo = certinfo->next;	    }	}	location = location->next;    }}/* * list the ocsp cache */voidlist_ocsp_cache(bool utc, bool strict){    lock_ocsp_cache("list_ocsp_cache");    list_ocsp_locations(ocsp_cache, FALSE, utc, strict);    unlock_ocsp_cache("list_ocsp_cache");}/* moves a chunk to a memory position, chunk is freed afterwards * position pointer is advanced after the insertion point */static voidmv_chunk(u_char **pos, chunk_t content){    if (content.len > 0)    {	chunkcpy(*pos, content);	freeanychunk(content);    }}static boolget_ocsp_requestor_cert(ocsp_location_t *location){    x509cert_t *cert = NULL;    /* initialize temporary static storage */    ocsp_requestor_cert = NULL;    ocsp_requestor_sc   = NULL;    ocsp_requestor_pri  = NULL;    for (;;)    {	char buf[BUF_LEN];	/* looking for a certificate from the same issuer */	cert = get_x509cert(location->issuer, location->authKeySerialNumber		    ,location->authKeyID, cert);   	if (cert == NULL)	    break;	DBG(DBG_CONTROL,	    dntoa(buf, BUF_LEN, cert->subject);	    DBG_log("candidate: '%s'", buf);	)	if (cert->smartcard)	{#ifdef SMARTCARD	    /* look for a matching private key on a smartcard */	    smartcard_t *sc = scx_get(cert);	    if (sc != NULL)	    {		DBG(DBG_CONTROL,		    DBG_log("matching smartcard found")		)		if (sc->valid)		{		    ocsp_requestor_cert = cert;		    ocsp_requestor_sc = sc;		    return TRUE;		}		plog("unable to sign ocsp request without PIN");	    }#endif	}	else	{	    /* look for a matching private key in the chained list */	    const struct RSA_private_key *pri = get_x509_private_key(cert);	    if (pri != NULL)	    {		DBG(DBG_CONTROL,		    DBG_log("matching private key found")		)		ocsp_requestor_cert = cert;		ocsp_requestor_pri = pri;		return TRUE;	    }	}    }    return FALSE;}static chunk_tgenerate_signature(chunk_t digest, smartcard_t *sc    , const struct RSA_private_key *pri){    chunk_t sigdata;    u_char *pos;    size_t siglen = 0;    if (sc != NULL)    {	/* RSA signature is done on smartcard */#ifdef SMARTCARD	if (!scx_establish_context(sc->reader))	{	    scx_release_context();	    return empty_chunk;	}	siglen = scx_get_keylength(sc) / BITS_PER_BYTE;	if (siglen == 0)	{	    plog("failed to get keylength from smartcard");	    scx_release_context();	    return empty_chunk;	}	DBG(DBG_CONTROL | DBG_CRYPT,	    DBG_log("signing hash with RSA key from smartcard (reader: %d, id: %s)"		, sc->reader, sc->id)	)	pos = build_asn1_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);	*pos++ = 0x00;	scx_sign_hash(sc, digest.ptr, digest.len, pos, siglen);	scx_release_context();#endif    }    else    {	/* RSA signature is done in software */	siglen = pri->pub.k;	pos = build_asn1_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);	*pos++ = 0x00;	sign_hash(pri, digest.ptr, digest.len, pos, siglen);    }    return sigdata;}/* * build signature into ocsp request * gets built only if a request cert with * a corresponding private key is found */static chunk_tbuild_signature(chunk_t tbsRequest){    chunk_t signature, sigdata, certs;    chunk_t digest, digest_info;    u_char *pos;    u_char digest_buf[MAX_DIGEST_LEN];    chunk_t digest_raw = { digest_buf, MAX_DIGEST_LEN };    if (!compute_digest(tbsRequest, OID_SHA1_WITH_RSA, &digest_raw))	return empty_chunk;    /* according to PKCS#1 v2.1 digest must be packaged into     * an ASN.1 structure for encryption     */    pos = build_asn1_object(&digest, ASN1_OCTET_STRING	    , digest_raw.len);    chunkcpy(pos, digest_raw);    pos = build_asn1_object(&digest_info, ASN1_SEQUENCE	    , sizeof(ASN1_sha1_id) + digest.len);    constcpy( pos, ASN1_sha1_id);    mv_chunk(&pos, digest);    /* generate the RSA signature */    sigdata = generate_signature(digest_info	, ocsp_requestor_sc	, ocsp_requestor_pri);    freeanychunk(digest_info);        /* has the RSA signature generation been successful? */

⌨️ 快捷键说明

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