Ejemplo n.º 1
0
/*
 * Checks if CA a is trusted by CA b
 */
bool trusted_ca(chunk_t a, chunk_t b, int *pathlen)
{
	bool match = FALSE;
	char abuf[ASN1_BUF_LEN], bbuf[ASN1_BUF_LEN];

	dntoa(abuf, ASN1_BUF_LEN, a);
	dntoa(bbuf, ASN1_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;
}
Ejemplo n.º 2
0
/*
 *  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;
}
Ejemplo n.º 3
0
Archivo: x509.c Proyecto: OPSF/uClinux
/*
 *  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;
}
Ejemplo n.º 4
0
/*
 * compare two ocsp locations for equality
 */
static bool
same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b)
{
    return ((a->authKeyID.ptr != NULL)
		? same_keyid(a->authKeyID, b->authKeyID)
		: (same_dn(a->issuer, b->issuer)
		    && same_serial(a->authKeySerialNumber, b->authKeySerialNumber)))
	    && same_chunk(a->uri, b->uri);
}
Ejemplo n.º 5
0
/* compare two struct id values */
bool
same_id(const struct id *a, const struct id *b)
{
    a = resolve_myid(a);
    b = resolve_myid(b);

    if(b->kind == ID_NONE || a->kind==ID_NONE) {
	return TRUE;    /* it's the wildcard */
    }

    if (a->kind != b->kind)
	return FALSE;
    
    switch (a->kind)
    {
    case ID_NONE:
	return TRUE;	/* repeat of above for completeness */

    case ID_IPV4_ADDR:
    case ID_IPV6_ADDR:
	return sameaddr(&a->ip_addr, &b->ip_addr);

    case ID_FQDN:
    case ID_USER_FQDN:
	/* assumptions:
	 * - case should be ignored
	 * - trailing "." should be ignored (even if the only character?)
	 */
	{
	    size_t al = a->name.len
		, bl = b->name.len;

	    while (al > 0 && a->name.ptr[al - 1] == '.')
		al--;
	    while (bl > 0 && b->name.ptr[bl - 1] == '.')
		bl--;
	    return al == bl
		&& strncasecmp((char *)a->name.ptr
			       , (char *)b->name.ptr, al) == 0;
	}

    case ID_DER_ASN1_DN:
	return same_dn(a->name, b->name);

    case ID_KEY_ID:
	return a->name.len == b->name.len
	    && memcmp(a->name.ptr, b->name.ptr, a->name.len) == 0;

    default:
	bad_case(a->kind);
    }
    /* NOTREACHED */
    return FALSE;
}
Ejemplo n.º 6
0
Archivo: x509.c Proyecto: mkj/libreswan
/*
 *  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;
}
Ejemplo n.º 7
0
/*
 * get a cacert with a given subject or keyid from an alternative list
 */
static const x509cert_t*get_alt_cacert(chunk_t subject, chunk_t serial,
				       chunk_t keyid,
				       const x509cert_t *cert)
{
	while (cert != NULL) {
		if ((keyid.ptr != NULL) ? same_keyid(keyid,
						     cert->subjectKeyID) :
		    (same_dn(subject, cert->subject) &&
		     same_serial(serial, cert->serialNumber)))
			return cert;

		cert = cert->next;
	}
	return NULL;
}
Ejemplo n.º 8
0
Archivo: x509.c Proyecto: mkj/libreswan
/*
 * stores a chained list of end certs and CA certs
 *
 * @verified_ca is a copied list of the verified authcerts that have
 * been placed in the global authcert chain
 */
void store_x509certs(x509cert_t **firstcert, x509cert_t **verified_ca,
					     bool strict)
{
	x509cert_t *cacerts = NULL;
	x509cert_t **pp = firstcert;

	/* first extract CA certs, discarding root CA certs */

	while (*pp != NULL) {
		x509cert_t *cert = *pp;

		if (cert->isCA) {
			*pp = cert->next;

			/* we don't accept self-signed CA certs */
			if (same_dn(cert->issuer, cert->subject)) {
				libreswan_log("self-signed cacert rejected");
				free_x509cert(cert);
			} else {
				/* insertion into temporary chain of candidate CA certs */
				cert->next = cacerts;
				cacerts = cert;
			}
		} else {
			pp = &cert->next;
		}
	}

	/* now verify the candidate CA certs */
	x509cert_t *ver = NULL;

	while (cacerts != NULL) {
		realtime_t valid_until;
		x509cert_t *cert = cacerts;

		cacerts = cacerts->next;

		if (trust_authcert_candidate(cert, cacerts) &&
		    verify_x509cert(cert, strict, &valid_until, cacerts)) {
			add_authcert(cert, AUTH_CA);
			if (ver == NULL) {
				ver = clone_thing(*cert, "x509cert_t");
				*verified_ca = ver;
			} else {
				ver->next = clone_thing(*cert, "x509cert_t");
				ver = ver->next;
			}
			ver->next = NULL;
		} else {
			libreswan_log("intermediate cacert rejected");
			free_x509cert(cert);
		}
	}

	/* now verify the end certificates */

	pp = firstcert;

	while (*pp != NULL) {
		realtime_t valid_until;
		x509cert_t *cert = *pp;

		if (verify_x509cert(cert, strict, &valid_until, NULL)) {
			DBG(DBG_X509 | DBG_PARSING,
			    DBG_log("public key validated"));
			add_x509_public_key(NULL, cert, valid_until,
					    DAL_SIGNED);
		} else {
			libreswan_log("X.509 certificate rejected");
		}
		*pp = cert->next;
		free_x509cert(cert);
	}
}
Ejemplo n.º 9
0
/* compare two struct id values */
bool same_id(const struct id *a, const struct id *b)
{
	a = resolve_myid(a);
	b = resolve_myid(b);

	if (b->kind == ID_NONE || a->kind == ID_NONE) {
		DBG(DBG_PARSING, DBG_log("id type with ID_NONE means wildcard match"));
		return TRUE; /* it's the wildcard */
	}

	if (a->kind != b->kind) {
		return FALSE;
	}

	switch (a->kind) {
	case ID_NONE:
		return TRUE; /* repeat of above for completeness */

	case ID_NULL:
		if (a->kind == b->kind) {
			DBG(DBG_PARSING, DBG_log("ID_NULL: id kind matches"));
			return TRUE;
		}
		return FALSE;

	case ID_IPV4_ADDR:
	case ID_IPV6_ADDR:
		return sameaddr(&a->ip_addr, &b->ip_addr);

	case ID_FQDN:
	case ID_USER_FQDN:
		/*
		 * assumptions:
		 * - case should be ignored
		 * - trailing "." should be ignored
		 *   (even if the only character?)
		 */
	{
		size_t al = a->name.len,
			bl = b->name.len;

		while (al > 0 && a->name.ptr[al - 1] == '.')
			al--;
		while (bl > 0 && b->name.ptr[bl - 1] == '.')
			bl--;
		return al == bl &&
			strncaseeq((char *)a->name.ptr,
				(char *)b->name.ptr, al);
	}

	case ID_FROMCERT:
		DBG(DBG_CONTROL,
			DBG_log("same_id() received ID_FROMCERT - unexpected"));
		/* FALLTHROUGH */
	case ID_DER_ASN1_DN:
		return same_dn(a->name, b->name);

	case ID_KEY_ID:
		return a->name.len == b->name.len &&
			memeq(a->name.ptr, b->name.ptr, a->name.len);

	default:
		bad_case(a->kind);
		/* NOTREACHED */
		return FALSE;
	}
}
Ejemplo n.º 10
0
/* establish trust into a candidate authcert by going up the trust chain.
 * validity and revocation status are not checked.
 */
bool
trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
{
    int pathlen;

    lock_authcert_list("trust_authcert_candidate");

    for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
    {
       const x509cert_t *authcert = NULL;

       DBG(DBG_CONTROL,
           char buf[ASN1_BUF_LEN];
           dntoa(buf, ASN1_BUF_LEN, cert->subject);
           DBG_log("subject: '%s'",buf);
           dntoa(buf, ASN1_BUF_LEN, cert->issuer);
           DBG_log("issuer:  '%s'",buf);
           if (cert->authKeyID.ptr != NULL)
           {
               datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
                   , buf, ASN1_BUF_LEN);
               DBG_log("authkey:  %s", buf);
           }
	   );

       /* search in alternative chain first */
       authcert = get_alt_cacert(cert->issuer, cert->authKeySerialNumber
           , cert->authKeyID, alt_chain);

       if (authcert != NULL)
       {
           DBG(DBG_CONTROL,
               DBG_log("issuer cacert found in alternative chain")
           )
       }
       else
       {
           /* search in trusted chain */
           authcert = get_authcert(cert->issuer, cert->authKeySerialNumber
               , cert->authKeyID, AUTH_CA);

           if (authcert != NULL)
           {
               DBG(DBG_CONTROL,
                   DBG_log("issuer cacert found")
               )
           }
           else
           {
               plog("issuer cacert not found");
               unlock_authcert_list("trust_authcert_candidate");
               return FALSE;
           }
       }

       if (!check_signature(cert->tbsCertificate, cert->signature,
                            cert->algorithm, authcert))
       {
           plog("invalid certificate signature");
           unlock_authcert_list("trust_authcert_candidate");
           return FALSE;
       }
       DBG(DBG_CONTROL,
           DBG_log("valid certificate signature")
       )

       /* check if cert is a self-signed root ca */
       if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
       {
           DBG(DBG_CONTROL,
               DBG_log("reached self-signed root ca")
           )
           unlock_authcert_list("trust_authcert_candidate");
           return TRUE;
       }

       /* go up one step in the trust chain */
       cert = authcert;
    }