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

📄 x509.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 5 页
字号:
same_x509cert(const x509cert_t *a, const x509cert_t *b){    return same_chunk(a->signature, b->signature);}/*  for each link pointing to the certificate "  increase the count by one */voidshare_x509cert(x509cert_t *cert){    if (cert != NULL) 	cert->count++;}/* *  add a X.509 user/host certificate to the chained list */x509cert_t*add_x509cert(x509cert_t *cert){    x509cert_t *c = x509certs;    while (c != NULL)    {	if (same_x509cert(c, cert)) /* already in chain, free cert */	{	    free_x509cert(cert);	    return c;	}	c = c->next;    }    /* insert new cert at the root of the chain */    lock_certs_and_keys("add_x509cert");    cert->next = x509certs;    x509certs = cert;    unlock_certs_and_keys("add_x509cert");    return cert;}/* * choose either subject DN or a subjectAltName as connection end ID */voidselect_x509cert_id(x509cert_t *cert, struct id *end_id){    bool copy_subject_dn = TRUE;	 /* ID is subject DN */    if (end_id->kind != ID_NONE) /* check for matching subjectAltName */    {	generalName_t *gn = cert->subjectAltName;	while (gn != NULL)	{	    struct id id = empty_id;	    gntoid(&id, gn);	    if (same_id(&id, end_id))	    {		copy_subject_dn = FALSE; /* take subjectAltName instead */		break;	    }	    gn = gn->next;	}    }    if (copy_subject_dn)    {	if (end_id->kind != ID_NONE && end_id->kind != ID_DER_ASN1_DN)	{	     char buf[IDTOA_BUF];	     idtoa(end_id, buf, IDTOA_BUF);	     openswan_log("  no subjectAltName matches ID '%s', replaced by subject DN", buf);	}	end_id->kind = ID_DER_ASN1_DN;	end_id->name.len = cert->subject.len;	end_id->name.ptr = temporary_cyclic_buffer();	memcpy(end_id->name.ptr, cert->subject.ptr, cert->subject.len);    }}/* * check for equality between two key identifiers */boolsame_keyid(chunk_t a, chunk_t b){    if (a.ptr == NULL || b.ptr == NULL)	return FALSE;    return same_chunk(a, b);}/* * check for equality between two serial numbers */boolsame_serial(chunk_t a, chunk_t b){    /* do not compare serial numbers if one of them is not defined */    if (a.ptr == NULL || b.ptr == NULL)	return TRUE;    return same_chunk(a, b);}/* *  get a X.509 certificate with a given issuer found at a certain position */x509cert_t*get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid, x509cert_t *chain){    x509cert_t *cert = (chain != NULL)? chain->next : x509certs;    while (cert != NULL)    {	if ((keyid.ptr != NULL) ? same_keyid(keyid, cert->authKeyID)	    : (same_dn(issuer, cert->issuer)	       && same_serial(serial, cert->authKeySerialNumber)))	{	    return cert;	}	cert = cert->next;    }    return NULL;}/* *  get a X.509 authority certificate with a given subject or keyid */x509cert_t*get_authcert(chunk_t subject, chunk_t serial, chunk_t keyid, u_char auth_flags){    x509cert_t *cert = x509authcerts;    x509cert_t *prev_cert = NULL;    while (cert != NULL)    {	if (cert->authority_flags & auth_flags	&& ((keyid.ptr != NULL) ? same_keyid(keyid, cert->subjectKeyID)	    : (same_dn(subject, cert->subject)	       && same_serial(serial, cert->serialNumber))))	{	    if (cert != x509authcerts)	    {		/* bring the certificate up front */		prev_cert->next = cert->next;		cert->next = x509authcerts;		x509authcerts = cert;	    }	    return cert;	}	prev_cert = cert;	cert = cert->next;    }    return NULL;}/* * Checks if CA a is trusted by CA b */booltrusted_ca(chunk_t a, chunk_t b, int *pathlen){    bool match = FALSE;    char abuf[BUF_LEN], bbuf[BUF_LEN];    dntoa(abuf, BUF_LEN, a);    dntoa(bbuf, BUF_LEN, b);    DBG(DBG_X509 | DBG_CONTROLMORE	, DBG_log("  trusted_ca called with a=%s b=%s"		  , abuf, bbuf));    /* no CA b specified -> any CA a is accepted */    if (b.ptr == NULL)    {	*pathlen = (a.ptr == NULL)? 0 : MAX_CA_PATH_LEN;	return TRUE;    }    /* no CA a specified -> trust cannot be established */    if (a.ptr == NULL)    {	*pathlen = MAX_CA_PATH_LEN;	return FALSE;    }    *pathlen = 0;    /* CA a equals CA b -> we have a match */    if (same_dn(a, b))	return TRUE;    /* CA a might be a subordinate CA of b */    lock_authcert_list("trusted_ca");    while ((*pathlen)++ < MAX_CA_PATH_LEN)    {	x509cert_t *cacert = get_authcert(a, empty_chunk, empty_chunk, AUTH_CA);	/* cacert not found or self-signed root cacert-> exit */	if (cacert == NULL || same_dn(cacert->issuer, a))	    break;	/* does the issuer of CA a match CA b? */	match = same_dn(cacert->issuer, b);	/* we have a match and exit the loop */	if (match)	    break;	/* go one level up in the CA chain */	a = cacert->issuer;    }        unlock_authcert_list("trusted_ca");    DBG(DBG_X509 | DBG_CONTROLMORE	, DBG_log("  trusted_ca returning with %s", match ? "match" : "failed"));    return match;}/*  * does our CA match one of the requested CAs? */boolmatch_requested_ca(generalName_t *requested_ca, chunk_t our_ca, int *our_pathlen){    /* if no ca is requested than any ca will match */    if (requested_ca == NULL)    {	*our_pathlen = 0;	return TRUE;    }    *our_pathlen = MAX_CA_PATH_LEN + 1;    while (requested_ca != NULL)    {	int pathlen;	if (trusted_ca(our_ca, requested_ca->name, &pathlen)	&& pathlen < *our_pathlen)	    *our_pathlen = pathlen;	requested_ca = requested_ca->next;    }    return *our_pathlen <= MAX_CA_PATH_LEN;}/* *  get the X.509 CRL with a given issuer */static x509crl_t*get_x509crl(chunk_t issuer, chunk_t serial, chunk_t keyid){    x509crl_t *crl = x509crls;    x509crl_t *prev_crl = NULL;    while(crl != NULL)    {	if ((keyid.ptr != NULL && crl->authKeyID.ptr != NULL)	? same_keyid(keyid, crl->authKeyID)	: (same_dn(crl->issuer, issuer) && same_serial(serial, crl->authKeySerialNumber)))	{	    if (crl != x509crls)	    {		/* bring the CRL up front */		prev_crl->next = crl->next;		crl->next = x509crls;		x509crls = crl;	    }	    return crl;	}	prev_crl = crl;	crl = crl->next;    }    return NULL;}/* *  free the dynamic memory used to store generalNames */voidfree_generalNames(generalName_t* gn, bool free_name){    while (gn != NULL)    {	generalName_t *gn_top = gn;	if (free_name)	{	    pfree(gn->name.ptr);	}	gn = gn->next;	pfree(gn_top);    }}/* *  free a X.509 certificate */voidfree_x509cert(x509cert_t *cert){    if (cert != NULL)    {	free_generalNames(cert->subjectAltName, FALSE);	free_generalNames(cert->crlDistributionPoints, FALSE);	pfreeany(cert->certificate.ptr);	pfree(cert);	cert = NULL;    }}/*  release of a certificate decreases the count by one "  the certificate is freed when the counter reaches zero */voidrelease_x509cert(x509cert_t *cert){    if (cert != NULL && --cert->count == 0)    {	x509cert_t **pp = &x509certs;	while (*pp != cert)	    pp = &(*pp)->next;	lock_certs_and_keys("release_x509cert");        *pp = cert->next;	unlock_certs_and_keys("release_x509cert");	free_x509cert(cert);    }}/* *  free the first authority certificate in the chain */static voidfree_first_authcert(void){    x509cert_t *first = x509authcerts;    x509authcerts = first->next;    free_x509cert(first);}/* *  free  all CA certificates */voidfree_authcerts(void){    lock_authcert_list("free_authcerts");    while (x509authcerts != NULL)        free_first_authcert();    unlock_authcert_list("free_authcerts");}/* *  free the dynamic memory used to store revoked certificates */static voidfree_revoked_certs(revokedCert_t* revokedCerts){    while (revokedCerts != NULL)    {	revokedCert_t * revokedCert = revokedCerts;	revokedCerts = revokedCert->next;	pfree(revokedCert);    }}/* *  free the dynamic memory used to store CRLs */voidfree_crl(x509crl_t *crl){    free_revoked_certs(crl->revokedCertificates);    free_generalNames(crl->distributionPoints, TRUE);    pfree(crl->certificateList.ptr);    pfree(crl);}static voidfree_first_crl(void){    x509crl_t *crl = x509crls;    x509crls = crl->next;    free_crl(crl);}voidfree_crls(void){    lock_crl_list("free_crls");    while (x509crls != NULL)	free_first_crl();    unlock_crl_list("free_crls");}/* * add an authority certificate to the chained list */voidadd_authcert(x509cert_t *cert, u_char auth_flags){    x509cert_t *old_cert;    /* set authority flags */    cert->authority_flags |= auth_flags;    lock_authcert_list("add_authcert");    old_cert = get_authcert(cert->subject, cert->serialNumber	, cert->subjectKeyID, auth_flags);    if (old_cert != NULL)    {	if (same_x509cert(cert, old_cert))	{	    /* cert is already present, just add additional authority flags */	    old_cert->authority_flags |= cert->authority_flags;	    DBG(DBG_X509 | DBG_PARSING ,		DBG_log("  authcert is already present and identical")	    )	    unlock_authcert_list("add_authcert");	    	    free_x509cert(cert);	    return;	}	else	{	    /* cert is already present but will be replaced by new cert */	    free_first_authcert();	    DBG(DBG_X509 | DBG_PARSING ,		DBG_log("  existing authcert deleted")	    )	}    }        /* add new authcert to chained list */    cert->next = x509authcerts;    x509authcerts = cert;    share_x509cert(cert);  /* set count to one */    DBG(DBG_X509 | DBG_PARSING,	DBG_log("  authcert inserted")    )    unlock_authcert_list("add_authcert");}/* *  Loads authority certificates */voidload_authcerts(const char *type, const char *path, u_char auth_flags){    struct dirent **filelist;    u_char buf[BUF_LEN];    u_char *save_dir;    int n;    /* change directory to specified path */    save_dir = getcwd(buf, BUF_LEN);    if (chdir(path))    {	openswan_log("Could not change to directory '%s'", path);    }    else    {	openswan_log("Changing to directory '%s'", path);	n = scandir(path, &filelist, file_select, alphasort);	if (n < 0)	    openswan_log("  scandir() error");	else	{	    while (n--)	    {		cert_t cert;		if (load_cert(CERT_NONE, filelist[n]->d_name, type, &cert))		    add_authcert(cert.u.x509, auth_flags);		free(filelist[n]);	    }	    free(filelist);	}    }    /* restore directory path */    chdir(save_dir);}/* * stores a chained list of end certs and CA certs */voidstore_x509certs(x509cert_t **firstcert, bool strict){    x509cert_t *cacerts = NULL;    x509cert_t **pp = firstcert;    /* first extract CA certs, discarding root CA certs */

⌨️ 快捷键说明

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