Пример #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;
}
Пример #2
0
/*
 * check if any crls are about to expire
 */
void check_crls(void)
{
	x509crl_t *crl;

	lock_crl_list("check_crls");
	crl = x509crls;

	while (crl != NULL) {
		deltatime_t time_left = realtimediff(crl->nextUpdate, realnow());
		char buf[ASN1_BUF_LEN];

		DBG(DBG_X509, {
			    dntoa(buf, ASN1_BUF_LEN, crl->issuer);
			    DBG_log("issuer: '%s'", buf);
			    if (crl->authKeyID.ptr != NULL) {
				    datatot(crl->authKeyID.ptr,
					    crl->authKeyID.len, ':',
					    buf, ASN1_BUF_LEN);
				    DBG_log("authkey: %s", buf);
			    }
			    DBG_log("%ld seconds left", (long)deltasecs(time_left));
		    });
		if (deltaless(time_left, deltatimescale(2, 1, crl_check_interval)))
			add_crl_fetch_request(crl->issuer,
					      crl->distributionPoints);
		crl = crl->next;
	}
Пример #3
0
/*
 * check if any crls are about to expire
 */
void
check_crls(void)
{
#ifdef HAVE_THREADS
    x509crl_t *crl;
    time_t current_time = time(NULL);

    lock_crl_list("check_crls");
    crl = x509crls;

    while (crl != NULL)
    {
	time_t time_left = crl->nextUpdate - current_time;
	u_char buf[ASN1_BUF_LEN];

	DBG(DBG_X509,
	    dntoa(buf, ASN1_BUF_LEN, crl->issuer);
	    DBG_log("issuer: '%s'",buf);
	    if (crl->authKeyID.ptr != NULL)
	    {
		datatot(crl->authKeyID.ptr, crl->authKeyID.len, ':'
		    , buf, ASN1_BUF_LEN);
		DBG_log("authkey: %s", buf);
	    }
	    DBG_log("%ld seconds left", time_left)
	)
	if (time_left < 2*crl_check_interval)
	    add_crl_fetch_request(crl->issuer, crl->distributionPoints);
	crl = crl->next;
    }
    unlock_crl_list("check_crls");
#endif
}
Пример #4
0
/*
 * check if an ocsp status is about to expire
 */
void
check_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;
    }
Пример #5
0
/*
 * verify if a cert hasn't been revoked by a crl
 */
static bool verify_by_crl(/*const*/ x509cert_t *cert, bool strict,
				    realtime_t *until)
{
	x509crl_t *crl;
	char ibuf[ASN1_BUF_LEN], cbuf[ASN1_BUF_LEN];

	lock_crl_list("verify_by_crl");
	crl = get_x509crl(cert->issuer, cert->authKeySerialNumber,
			  cert->authKeyID);

	dntoa(ibuf, ASN1_BUF_LEN, cert->issuer);

	if (crl == NULL) {
		unlock_crl_list("verify_by_crl");
		libreswan_log("no crl from issuer \"%s\" found (strict=%s)",
			      ibuf,
			      strict ? "yes" : "no");

#if defined(LIBCURL) || defined(LDAP_VER)
		if (cert->crlDistributionPoints != NULL) {
			add_crl_fetch_request(cert->issuer,
					      cert->crlDistributionPoints);
			wake_fetch_thread("verify_by_crl");
		}
#endif
		if (strict)
			return FALSE;
	} else {
		x509cert_t *issuer_cert;
		bool valid;

		DBG(DBG_X509,
		    DBG_log("issuer crl \"%s\" found", ibuf));

#if defined(LIBCURL) || defined(LDAP_VER)
		add_distribution_points(cert->crlDistributionPoints,
					&crl->distributionPoints);
#endif

		lock_authcert_list("verify_by_crl");

		issuer_cert = get_authcert(crl->issuer,
					   crl->authKeySerialNumber,
					   crl->authKeyID, AUTH_CA);
		dntoa(cbuf, ASN1_BUF_LEN, crl->issuer);
		valid = check_signature(crl->tbsCertList, crl->signature,
					crl->algorithm, issuer_cert);

		unlock_authcert_list("verify_by_crl");

		if (valid) {
			bool revoked_crl, expired_crl;

			DBG(DBG_X509,
			    DBG_log("valid crl signature on \"%s\"", cbuf));

			/* with strict crl policy the public key must have the same
			 * lifetime as the crl
			 */
			if (strict && realbefore(crl->nextUpdate, *until))
				*until = crl->nextUpdate;

			/* has the certificate been revoked? */
			revoked_crl = x509_check_revocation(crl,
							    cert->serialNumber);

			/* is the crl still valid? */
			expired_crl = realbefore(crl->nextUpdate, realnow());

			unlock_crl_list("verify_by_crl");

			if (expired_crl) {
				char tbuf[REALTIMETOA_BUF];

				libreswan_log(
					"crl update for \"%s\" is overdue since %s",
					cbuf,
					realtimetoa(crl->nextUpdate, TRUE,
						tbuf, sizeof(tbuf)));

#if defined(LIBCURL) || defined(LDAP_VER)
				/* try to fetch a crl update */
				if (cert->crlDistributionPoints != NULL) {
					add_crl_fetch_request(cert->issuer,
							      cert->crlDistributionPoints);
					wake_fetch_thread("verify_by_crl");
				}
#endif
			} else {
				DBG(DBG_X509,
				    DBG_log("crl is \"%s\" valid", cbuf));
			}

			if (revoked_crl || (strict && expired_crl)) {
				/* remove any cached public keys */
				remove_x509_public_key(cert);
				return FALSE;
			}
		} else {
			unlock_crl_list("verify_by_crl");
			libreswan_log("invalid crl signature on \"%s\"", cbuf);
			if (strict)
				return FALSE;
		}
	}
	return TRUE;
}
Пример #6
0
int
idtoa(const struct id *id, char *dst, size_t dstlen)
{
    int n;

    id = resolve_myid(id);
    switch (id->kind)
    {
    case ID_MYID:
	n = snprintf(dst, dstlen, "%s", "%myid");
	break;
    case ID_FROMCERT:
	n = snprintf(dst, dstlen, "%s", "%fromcert");
	break;
    case ID_NONE:
	n = snprintf(dst, dstlen, "%s", "(none)");
	break;
    case ID_IPV4_ADDR:
    case ID_IPV6_ADDR:
	if(isanyaddr(&id->ip_addr)) {
	    dst[0]='\0';
	    strncat(dst, "%any", dstlen);
	    n = strlen(dst);
	} else {
	    n = (int)addrtot(&id->ip_addr, 0, dst, dstlen) - 1;
	}
	break;
    case ID_FQDN:
	n = snprintf(dst, dstlen, "@%.*s", (int)id->name.len, id->name.ptr);
	break;
    case ID_USER_FQDN:
	n = snprintf(dst, dstlen, "%.*s", (int)id->name.len, id->name.ptr);
	break;
    case ID_DER_ASN1_DN:
	n = dntoa(dst, dstlen, id->name);
	break;
    case ID_KEY_ID:
	passert(dstlen > 4);
	dst[0]='@';
	dst[1]='#';
	dstlen-=2; dst+=2;
	n = keyidtoa(dst, dstlen, id->name);
	n+= 2;
	break;
    default:
	n = snprintf(dst, dstlen, "unknown id kind %d", id->kind);
	break;
    }

    /* "Sanitize" string so that log isn't endangered:
     * replace unprintable characters with '?'.
     */
    if (n > 0)
    {
	for ( ; *dst != '\0'; dst++)
	    if (!isprint(*dst))
		*dst = '?';
    }

    return n;
}
Пример #7
0
static int dntoasi(char *dst, size_t dstlen, SECItem si)
{
	chunk_t ch = same_secitem_as_chunk(si);

	return dntoa(dst, dstlen, ch);
}
Пример #8
0
/* x509.c SEAM */
static void
list_x509cert_chain(const char *caption, x509cert_t* cert, u_char auth_flags
 , bool utc)
{
    bool first = TRUE;
    time_t tnow;

    /* determine the current time */
    time(&tnow);

    while (cert != NULL)
    {
	if (auth_flags == AUTH_NONE || (auth_flags & cert->authority_flags))
	{
	    unsigned keysize;
	    char keyid[KEYID_BUF];
	    char buf[ASN1_BUF_LEN];
	    char tbuf[TIMETOA_BUF];

	    cert_t c;

	    c.type = CERT_X509_SIGNATURE;
	    c.u.x509 = cert;

	    if (first)
	    {
		DBG_log( " ");
		DBG_log( "List of X.509 %s Certificates:", caption);
		DBG_log( " ");
		first = FALSE;
	    }

	    DBG_log( "NOW, count: %d", cert->count);
	    dntoa(buf, ASN1_BUF_LEN, cert->subject);
	    DBG_log( "       subject: '%s'", buf);
	    dntoa(buf, ASN1_BUF_LEN, cert->issuer);
	    DBG_log( "       issuer:  '%s'", buf);
	    datatot(cert->serialNumber.ptr, cert->serialNumber.len, ':'
		, buf, ASN1_BUF_LEN);
	    DBG_log( "       serial:   %s", buf);
	    form_keyid(cert->publicExponent, cert->modulus, keyid, &keysize);
	    DBG_log( "       pubkey:   %4d RSA Key %s"
                    , 8*keysize, keyid);
	    DBG_log( "       validity: not before %s %s",
		timetoa(&cert->notBefore, utc, tbuf, sizeof(tbuf)),
		(cert->notBefore < tnow)?"ok":"fatal (not valid yet)");
	    DBG_log( "                 not after  %s %s",
		timetoa(&cert->notAfter, utc, tbuf, sizeof(tbuf)),
		check_expiry(cert->notAfter, CA_CERT_WARNING_INTERVAL, TRUE));
	    if (cert->subjectKeyID.ptr != NULL)
	    {
		datatot(cert->subjectKeyID.ptr, cert->subjectKeyID.len, ':'
		    , buf, ASN1_BUF_LEN);
		DBG_log( "       subjkey:  %s", buf);
	    }
	    if (cert->authKeyID.ptr != NULL)
	    {
		datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
		    , buf, ASN1_BUF_LEN);
		DBG_log( "       authkey:  %s", buf);
	    }
	    if (cert->authKeySerialNumber.ptr != NULL)
	    {
		datatot(cert->authKeySerialNumber.ptr, cert->authKeySerialNumber.len
		    , ':', buf, ASN1_BUF_LEN);
		DBG_log( "       aserial:  %s", buf);
	    }
	}
	cert = cert->next;
    }
}
Пример #9
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;
    }
Пример #10
0
static char *dntoasi(dntoasi_buf_t *dst, SECItem si)
{
	dntoa(dst->buf, sizeof(dst->buf), same_secitem_as_chunk(si));
	return dst->buf;
}