/*
 *  Loads PKCS#1 private key file
 */
pkcs1privkey_t*
load_pkcs1_private_key(const char* filename, const char* passphrase)
{
    chunk_t blob = empty_chunk;
    char path[512];

    if (*filename == '/')	/* absolute pathname */
    	strncpy(path, filename, sizeof(path));
    else			/* relative pathname */
	snprintf(path, sizeof(path), "%s/%s", PRIVATE_KEY_PATH, filename);

    if (load_asn1_file(path, passphrase, "private key", &blob))
    {
	pkcs1privkey_t *key = alloc_thing(pkcs1privkey_t, "pkcs1privkey");
	*key = empty_pkcs1privkey;
	if (parse_pkcs1_private_key(blob, key))
	    return key;
	else
	{
	    log("  error in PKCS#1 private key");
	    pfree(blob.ptr);
	    pfree(key);
	}
    }
    return NULL;
}
Beispiel #2
0
/*
 * Parse PKCS#7 wrapped X.509 certificates
 */
static bool parse_pkcs7_signedData(chunk_t blob, int level0, x509cert_t **cert)
{
	asn1_ctx_t ctx;
	chunk_t object;
	u_int level;
	u_int objectID = 0;

	asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);

	while (objectID < PKCS7_SIGNED_ROOF) {

		if (!extract_object(signedDataObjects, &objectID, &object,
				    &level, &ctx))
			return FALSE;

		if (objectID == PKCS7_SIGNED_CERT) {
			chunk_t cert_blob;
			x509cert_t *newcert = alloc_thing(x509cert_t,
							  "pkcs7 wrapped x509cert");

			clonetochunk(cert_blob, object.ptr, object.len,
				     "pkcs7 cert blob");
			*newcert = empty_x509cert;

			if (parse_x509cert(cert_blob, level + 1, newcert)) {
				newcert->next = *cert;
				*cert = newcert;
			} else {
				free_x509cert(newcert);
			}
		}
		objectID++;
	}
	return TRUE;
}
Beispiel #3
0
/*
 * parses ietfAttrSyntax
 */
static ietfAttrList_t*
parse_ietfAttrSyntax(chunk_t blob, int level0)
{
    asn1_ctx_t ctx;
    chunk_t object;
    u_int level;
    u_int objectID = 0;
    
    ietfAttrList_t *list = NULL;
	
    asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);

    while (objectID < IETF_ATTR_ROOF)
    {
       if (!extract_object(ietfAttrSyntaxObjects, &objectID, &object, &level, &ctx))
            return NULL;

       switch (objectID)
       {
       case IETF_ATTR_OCTETS:
       case IETF_ATTR_OID:
       case IETF_ATTR_STRING:
           {
               ietfAttr_t *attr   = alloc_thing(ietfAttr_t, "ietfAttr");
               ietfAttrList_t *el = alloc_thing(ietfAttrList_t, "ietfAttrList");
            
               attr->kind  = (objectID - IETF_ATTR_OCTETS) / 2;
               attr->value = object;
               attr->count = 0;
       
               el->attr = add_ietfAttr(attr);
               el->next = list;
               list = el;
           }
           break;
	default:
	   break;
	}
	objectID++;
    }
    return list;
}
Beispiel #4
0
/*   
 * decodes a comma separated list of group attributes
 */
void
decode_groups(char *groups, ietfAttrList_t **listp)
{
    if (groups == NULL)
      return;
 
    while (strlen(groups) > 0)
    {
      char *end;
      char *next = strchr(groups, ',');

      if (next == NULL)
         end = next = groups + strlen(groups);
      else
         end = next++;
 
      /* eat preceeding whitespace */
      while (groups < end && *groups == ' ')
          groups++;
      
      /* eat trailing whitespace */
      while (end > groups && *(end-1) == ' ')
          end--;
      
      if (groups < end)
      {
          ietfAttr_t *attr   = alloc_thing(ietfAttr_t, "ietfAttr");
          ietfAttrList_t *el = alloc_thing(ietfAttrList_t, "ietfAttrList");
          
          attr->kind  = IETF_ATTRIBUTE_STRING;
          attr->value.ptr = (unsigned char *)groups;
          attr->value.len = end - groups;
          attr->count = 0;
      
          el->attr = add_ietfAttr(attr);
          el->next = *listp;
          *listp = el;
      }
          
      groups = next;
    }
}
Beispiel #5
0
pb_stream *pbs_create(int size)
{
    pb_stream *n;
    void *mem;

    n = alloc_thing(*n, "pbs_create");
    mem=alloc_bytes(size, "pbs_memory");
    init_pbs(n, mem, size, "tpm_pbs");

    return n;
}      
Beispiel #6
0
/*
 * Decode the CR payload of Phase 1.
 */
void
decode_cr(struct msg_digest *md, generalName_t **requested_ca)
{
    struct payload_digest *p;

    for (p = md->chain[ISAKMP_NEXT_CR]; p != NULL; p = p->next)
    {
	struct isakmp_cr *const cr = &p->payload.cr;
	chunk_t ca_name;
	
	ca_name.len = pbs_left(&p->pbs);
	ca_name.ptr = (ca_name.len > 0)? p->pbs.cur : NULL;

	DBG_cond_dump_chunk(DBG_PARSING, "CR", ca_name);

	if (cr->isacr_type == CERT_X509_SIGNATURE)
	{

	    if (ca_name.len > 0)
	    {
		generalName_t *gn;
		
		if (!is_asn1(ca_name))
		    continue;

		gn = alloc_thing(generalName_t, "generalName");
		clonetochunk(ca_name, ca_name.ptr,ca_name.len, "ca name");
		gn->kind = GN_DIRECTORY_NAME;
		gn->name = ca_name;
		gn->next = *requested_ca;
		*requested_ca = gn;
	    }

	    DBG(DBG_PARSING | DBG_CONTROL,
		char buf[IDTOA_BUF];
		dntoa_or_null(buf, IDTOA_BUF, ca_name, "%any");
		DBG_log("requested CA: '%s'", buf);
	    )
	}
	else
	    loglog(RC_LOG_SERIOUS, "ignoring %s certificate request payload",
		   enum_show(&cert_type_names, cr->isacr_type));
    }
Beispiel #7
0
/*
 *  add an ietfAttribute to the chained list
 */
static ietfAttr_t*
add_ietfAttr(ietfAttr_t *attr)
{
    ietfAttrList_t **listp = &ietfAttributes;
    ietfAttrList_t *list = *listp;
    int cmp = -1;
    
    while (list != NULL)
    {
      cmp = cmp_ietfAttr(attr, list->attr);
      if (cmp <= 0)
          break;
      listp = &list->next;
      list = *listp;
    }
    
    if (cmp == 0)
    {
      /* attribute already exists, increase count */
      pfree(attr);
      list->attr->count++;
      return list->attr;
    }
    else
    {
      ietfAttrList_t *el = alloc_thing(ietfAttrList_t, "ietfAttrList");
    
      /* new attribute, unshare value */
      attr->value.ptr = clone_bytes(attr->value.ptr, attr->value.len
          , "attr value");
      attr->count = 1;
      time(&attr->installed);
     
      el->attr = attr;
      el->next = list;
      *listp = el;
    
      return attr;
    }
}
Beispiel #8
0
/*
 * Insert X.509 CRL into chained list
 */
bool insert_crl(chunk_t blob, chunk_t crl_uri)
{
	x509crl_t *crl = alloc_thing(x509crl_t, "x509crl");

	*crl = empty_x509crl;

	if (parse_x509crl(blob, 0, crl)) {
		x509cert_t *issuer_cert;
		x509crl_t *oldcrl;
		bool valid_sig;
		generalName_t *gn;

		/* add distribution point */
		gn = alloc_thing(generalName_t, "generalName");
		gn->kind = GN_URI;
		gn->name = crl_uri;
		gn->next = crl->distributionPoints;
		crl->distributionPoints = gn;

		lock_authcert_list("insert_crl");
		/* get the issuer cacert */
		issuer_cert = get_authcert(crl->issuer,
					   crl->authKeySerialNumber,
					   crl->authKeyID, AUTH_CA);

		if (issuer_cert == NULL) {
			chunk_t *n = &crl->distributionPoints->name;

			loglog(RC_LOG_SERIOUS,
			       "CRL rejected: crl issuer cacert not found for %.*s",
			       (int)n->len, (char *)n->ptr);

			free_crl(crl);
			unlock_authcert_list("insert_crl");
			return FALSE;
		}
		DBG(DBG_X509,
		    DBG_log("crl issuer cacert found"));

		/* check the issuer's signature of the crl */
		valid_sig = check_signature(crl->tbsCertList, crl->signature,
					    crl->algorithm, issuer_cert);
		unlock_authcert_list("insert_crl");

		if (!valid_sig) {
			free_crl(crl);
			return FALSE;
		}
		DBG(DBG_X509,
		    DBG_log("valid crl signature"));

		lock_crl_list("insert_crl");
		oldcrl = get_x509crl(crl->issuer, crl->authKeySerialNumber,
				     crl->authKeyID);

		if (oldcrl != NULL) {
			if (realbefore(oldcrl->thisUpdate, crl->thisUpdate)) {
				/* old CRL is older than new CRL: replace */
#if defined(LIBCURL) || defined(LDAP_VER)
				/* keep any known CRL distribution points */
				add_distribution_points(
					oldcrl->distributionPoints,
					&crl->distributionPoints);
#endif

				/* now delete the old CRL */
				free_first_crl();
				DBG(DBG_X509,
				    DBG_log("thisUpdate is newer - existing crl deleted"));
			} else {
				/* old CRL is not older than new CRL: keep old one */
				unlock_crl_list("insert_crls");
				DBG(DBG_X509,
				    DBG_log("thisUpdate is not newer - existing crl not replaced"));
				free_crl(crl);
				/*
				 * is the fetched crl valid?
				 * now + 2 * crl_check_interval < oldcrl->nextUpdate
				 */
				return realbefore(realtimesum(realnow(), deltatimescale(2, 1, crl_check_interval)), oldcrl->nextUpdate);
			}
		}

		/* insert new CRL */
		crl->next = x509crls;
		x509crls = crl;

		unlock_crl_list("insert_crl");

		/*
		 * is the new crl valid?
		 * now + 2 * crl_check_interval < crl->nextUpdate
		 */
		return realbefore(realtimesum(realnow(), deltatimescale(2, 1, crl_check_interval)), crl->nextUpdate);
	} else {
		loglog(RC_LOG_SERIOUS, "  error in X.509 crl %s",
		       (char *)crl_uri.ptr);
		free_crl(crl);
		return FALSE;
	}
}
Beispiel #9
0
/*
 * Insert X.509 CRL into chained list
 */
bool
insert_crl(chunk_t blob, chunk_t crl_uri)
{
    x509crl_t *crl = alloc_thing(x509crl_t, "x509crl");

    *crl = empty_x509crl;

    if (parse_x509crl(blob, 0, crl))
    {
	x509cert_t *issuer_cert;
	x509crl_t *oldcrl;
	bool valid_sig;
	generalName_t *gn;

	/* add distribution point */
	gn = alloc_thing(generalName_t, "generalName");
	gn->kind = GN_URI;
	gn->name = crl_uri;
	gn->next = crl->distributionPoints;
	crl->distributionPoints = gn;

	lock_authcert_list("insert_crl");
	/* get the issuer cacert */
	issuer_cert = get_authcert(crl->issuer, crl->authKeySerialNumber,
	    crl->authKeyID, AUTH_CA);

	if (issuer_cert == NULL)
	{
	    char distpoint[PATH_MAX];

	    distpoint[0] = '\0';
	    strncat(distpoint, (char *)crl->distributionPoints->name.ptr,
		    (crl->distributionPoints->name.len < PATH_MAX ?
		     crl->distributionPoints->name.len : PATH_MAX));
	    
	    openswan_log("crl issuer cacert not found for (%s)",
			 distpoint);;

	    free_crl(crl);
	    unlock_authcert_list("insert_crl");
	    return FALSE;
	}
	DBG(DBG_X509,
	    DBG_log("crl issuer cacert found")
	)

	/* check the issuer's signature of the crl */
	valid_sig = check_signature(crl->tbsCertList, crl->signature
			, crl->algorithm, issuer_cert);
	unlock_authcert_list("insert_crl");

	if (!valid_sig)
	{
	    free_crl(crl);
	    return FALSE;
	}
	DBG(DBG_X509,
	    DBG_log("valid crl signature")
	)

	lock_crl_list("insert_crl");
	oldcrl = get_x509crl(crl->issuer, crl->authKeySerialNumber
	    , crl->authKeyID);

	if (oldcrl != NULL)
	{
	    if (crl->thisUpdate > oldcrl->thisUpdate)
	    {
#ifdef HAVE_THREADS
		/* keep any known CRL distribution points */
		add_distribution_points(oldcrl->distributionPoints
		    , &crl->distributionPoints);
#endif

		/* now delete the old CRL */
		free_first_crl();
		DBG(DBG_X509,
		    DBG_log("thisUpdate is newer - existing crl deleted")
		)
	    }
	    else
	    {