Example #1
0
/*
 * Check if digest of one of the certificates from verified chain
 * is present in the forbidden database.
 * Since UEFI allows to store three types of digests
 * all of them have to be checked separately.
 */
static int
check_forbidden_digests(br_x509_certificate *xcs, size_t num)
{
	unsigned char sha256_digest[br_sha256_SIZE];
	unsigned char sha384_digest[br_sha384_SIZE];
	unsigned char sha512_digest[br_sha512_SIZE];
	void *tbs;
	hash_data *digest;
	br_hash_compat_context ctx;
	const br_hash_class *md;
	size_t tbs_len, i;
	int have_sha256, have_sha384, have_sha512;

	if (VEC_LEN(forbidden_digests) == 0)
		return (0);

	/*
	 * Iterate through certificates, extract their To-Be-Signed section,
	 * and compare its digest against the ones in the forbidden database.
	 */
	while (num--) {
		tbs = X509_to_tbs(xcs[num].data, &tbs_len);
		if (tbs == NULL) {
			printf("Failed to obtain TBS part of certificate\n");
			return (1);
		}
		have_sha256 = have_sha384 = have_sha512 = 0;

		for (i = 0; i < VEC_LEN(forbidden_digests); i++) {
			digest = &VEC_ELT(forbidden_digests, i);
			switch (digest->hash_size) {
			case br_sha256_SIZE:
				if (!have_sha256) {
					have_sha256 = 1;
					md = &br_sha256_vtable;
					md->init(&ctx.vtable);
					md->update(&ctx.vtable, tbs, tbs_len);
					md->out(&ctx.vtable, sha256_digest);
				}
				if (!memcmp(sha256_digest,
					digest->data,
					br_sha256_SIZE))
					return (1);

				break;
			case br_sha384_SIZE:
				if (!have_sha384) {
					have_sha384 = 1;
					md = &br_sha384_vtable;
					md->init(&ctx.vtable);
					md->update(&ctx.vtable, tbs, tbs_len);
					md->out(&ctx.vtable, sha384_digest);
				}
				if (!memcmp(sha384_digest,
					digest->data,
					br_sha384_SIZE))
					return (1);

				break;
			case br_sha512_SIZE:
				if (!have_sha512) {
					have_sha512 = 1;
					md = &br_sha512_vtable;
					md->init(&ctx.vtable);
					md->update(&ctx.vtable, tbs, tbs_len);
					md->out(&ctx.vtable, sha512_digest);
				}
				if (!memcmp(sha512_digest,
					digest->data,
					br_sha512_SIZE))
					return (1);

				break;
			}
		}
	}

	return (0);
}
Example #2
0
static int sort_axis( int axis,
		      int vec_size,
		      int vec_stride,
		      struct data_idx *indices,
		      int start,
		      int finish,
		      float *out,
		      int uniq,
		      const float fudge )
{
   int i;

   if (finish-start > 2)
   {
      qsort( indices+start, finish-start, sizeof(*indices), compare[axis] );
   }
   else if (indices[start].data[axis] > indices[start+1].data[axis])
   {
      struct data_idx tmp = indices[start];
      indices[start] = indices[start+1];
      indices[start+1] = tmp;
   }

   if (axis == vec_size-1) {
      for (i = start ; i < finish ; ) {
	 float max = indices[i].data[axis] + fudge;
	 float *dest = VEC_ELT(out, vec_stride, uniq);
	 int j;

	 for (j = 0 ; j < vec_size ; j++)
	    dest[j] = indices[i].data[j];

	 for ( ; i < finish && max >= indices[i].data[axis]; i++)
	    indices[i].uniq_idx = uniq;

	 uniq++;
      }
   } else {
      for (i = start ; i < finish ; ) {
	 int j = i + 1;
	 float max = indices[i].data[axis] + fudge;
	 while (j < finish && max >= indices[j].data[axis]) j++;
	 if (j == i+1) {
	    float *dest = VEC_ELT(out, vec_stride, uniq);
	    int k;

	    indices[i].uniq_idx = uniq;

	    for (k = 0 ; k < vec_size ; k++)
	       dest[k] = indices[i].data[k];

	    uniq++;
	 } else {
	    uniq = sort_axis( axis+1, vec_size, vec_stride,
			      indices, i, j, out, uniq, fudge );
	 }
	 i = j;
      }
   }

   return uniq;
}
Example #3
0
/**
 * if we can verify the certificate chain in "certs",
 * return the public key and if "xcp" is !NULL the associated
 * certificate
 */
static br_x509_pkey *
verify_signer_xcs(br_x509_certificate *xcs,
    size_t num,
    br_name_element *elts, size_t num_elts,
    anchor_list *anchors)
{
	br_x509_minimal_context mc;
	br_x509_certificate *xc;
	size_t u;
	cert_list chain = VEC_INIT;
	const br_x509_pkey *tpk;
	br_x509_pkey *pk;
	unsigned int usages;
	int err;

	DEBUG_PRINTF(5, ("verify_signer: %zu certs in chain\n", num));
	VEC_ADDMANY(chain, xcs, num);
	if (VEC_LEN(chain) == 0) {
		ve_error_set("ERROR: no/invalid certificate chain\n");
		return (NULL);
	}

	DEBUG_PRINTF(5, ("verify_signer: %zu trust anchors\n",
		VEC_LEN(*anchors)));

	br_x509_minimal_init(&mc, &br_sha256_vtable,
	    &VEC_ELT(*anchors, 0),
	    VEC_LEN(*anchors));
#ifdef VE_ECDSA_SUPPORT
	br_x509_minimal_set_ecdsa(&mc,
	    &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1);
#endif
#ifdef VE_RSA_SUPPORT
	br_x509_minimal_set_rsa(&mc, &br_rsa_i31_pkcs1_vrfy);
#endif
#if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT)
	/* This is deprecated! do not enable unless you absoultely have to */
	br_x509_minimal_set_hash(&mc, br_sha1_ID, &br_sha1_vtable);
#endif
	br_x509_minimal_set_hash(&mc, br_sha256_ID, &br_sha256_vtable);
#ifdef VE_SHA384_SUPPORT
	br_x509_minimal_set_hash(&mc, br_sha384_ID, &br_sha384_vtable);
#endif
#ifdef VE_SHA512_SUPPORT
	br_x509_minimal_set_hash(&mc, br_sha512_ID, &br_sha512_vtable);
#endif
	br_x509_minimal_set_name_elements(&mc, elts, num_elts);

#ifdef _STANDALONE
	/*
	 * Clock is probably bogus so we use ve_utc.
	 */
	mc.days = (ve_utc / SECONDS_PER_DAY) + X509_DAYS_TO_UTC0;
	mc.seconds = (ve_utc % SECONDS_PER_DAY);
#endif

	mc.vtable->start_chain(&mc.vtable, NULL);
	for (u = 0; u < VEC_LEN(chain); u ++) {
		xc = &VEC_ELT(chain, u);
		mc.vtable->start_cert(&mc.vtable, xc->data_len);
		mc.vtable->append(&mc.vtable, xc->data, xc->data_len);
		mc.vtable->end_cert(&mc.vtable);
		switch (mc.err) {
		case 0:
		case BR_ERR_X509_OK:
		case BR_ERR_X509_EXPIRED:
			break;
		default:
			printf("u=%zu mc.err=%d\n", u, mc.err);
			break;
		}
	}
	err = mc.vtable->end_chain(&mc.vtable);
	pk = NULL;
	if (err) {
		ve_error_set("Validation failed, err = %d", err);
	} else {
		tpk = mc.vtable->get_pkey(&mc.vtable, &usages);
		if (tpk != NULL) {
			pk = xpkeydup(tpk);
		}
	}
	VEC_CLEAR(chain);
	return (pk);
}