Exemplo n.º 1
0
static int pkcs7_to_cert(struct hs20_osu_client *ctx, const u8 *pkcs7,
			 size_t len, char *pem_file, char *der_file)
{
#ifdef OPENSSL_IS_BORINGSSL
	CBS pkcs7_cbs;
#else /* OPENSSL_IS_BORINGSSL */
	PKCS7 *p7 = NULL;
	const unsigned char *p = pkcs7;
#endif /* OPENSSL_IS_BORINGSSL */
	STACK_OF(X509) *certs;
	int i, num, ret = -1;
	BIO *out = NULL;

#ifdef OPENSSL_IS_BORINGSSL
	certs = sk_X509_new_null();
	if (!certs)
		goto fail;
	CBS_init(&pkcs7_cbs, pkcs7, len);
	if (!PKCS7_get_certificates(certs, &pkcs7_cbs)) {
		wpa_printf(MSG_INFO, "Could not parse PKCS#7 object: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		write_result(ctx, "Could not parse PKCS#7 object from EST");
		goto fail;
	}
#else /* OPENSSL_IS_BORINGSSL */
	p7 = d2i_PKCS7(NULL, &p, len);
	if (p7 == NULL) {
		wpa_printf(MSG_INFO, "Could not parse PKCS#7 object: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		write_result(ctx, "Could not parse PKCS#7 object from EST");
		goto fail;
	}

	switch (OBJ_obj2nid(p7->type)) {
	case NID_pkcs7_signed:
		certs = p7->d.sign->cert;
		break;
	case NID_pkcs7_signedAndEnveloped:
		certs = p7->d.signed_and_enveloped->cert;
		break;
	default:
		certs = NULL;
		break;
	}
#endif /* OPENSSL_IS_BORINGSSL */

	if (!certs || ((num = sk_X509_num(certs)) == 0)) {
		wpa_printf(MSG_INFO, "No certificates found in PKCS#7 object");
		write_result(ctx, "No certificates found in PKCS#7 object");
		goto fail;
	}

	if (der_file) {
		FILE *f = fopen(der_file, "wb");
		if (f == NULL)
			goto fail;
		i2d_X509_fp(f, sk_X509_value(certs, 0));
		fclose(f);
	}

	if (pem_file) {
		out = BIO_new(BIO_s_file());
		if (out == NULL ||
		    BIO_write_filename(out, pem_file) <= 0)
			goto fail;

		for (i = 0; i < num; i++) {
			X509 *cert = sk_X509_value(certs, i);
			X509_print(out, cert);
			PEM_write_bio_X509(out, cert);
			BIO_puts(out, "\n");
		}
	}

	ret = 0;

fail:
#ifdef OPENSSL_IS_BORINGSSL
	if (certs)
		sk_X509_pop_free(certs, X509_free);
#else /* OPENSSL_IS_BORINGSSL */
	PKCS7_free(p7);
#endif /* OPENSSL_IS_BORINGSSL */
	if (out)
		BIO_free_all(out);

	return ret;
}
Exemplo n.º 2
0
static int test_cert_reparse(const uint8_t *der_bytes, size_t der_len) {
  CBS pkcs7;
  CBB cbb;
  STACK_OF(X509) *certs = sk_X509_new_null();
  STACK_OF(X509) *certs2 = sk_X509_new_null();
  uint8_t *result_data, *result2_data;
  size_t result_len, result2_len, i;

  CBS_init(&pkcs7, der_bytes, der_len);
  if (!PKCS7_get_certificates(certs, &pkcs7)) {
    fprintf(stderr, "PKCS7_get_certificates failed.\n");
    return 0;
  }

  CBB_init(&cbb, der_len);
  if (!PKCS7_bundle_certificates(&cbb, certs) ||
      !CBB_finish(&cbb, &result_data, &result_len)) {
    fprintf(stderr, "PKCS7_bundle_certificates failed.\n");
    return 0;
  }

  CBS_init(&pkcs7, result_data, result_len);
  if (!PKCS7_get_certificates(certs2, &pkcs7)) {
    fprintf(stderr, "PKCS7_get_certificates reparse failed.\n");
    return 0;
  }

  if (sk_X509_num(certs) != sk_X509_num(certs2)) {
    fprintf(stderr, "Number of certs in results differ.\n");
    return 0;
  }

  for (i = 0; i < sk_X509_num(certs); i++) {
    X509 *a = sk_X509_value(certs, i);
    X509 *b = sk_X509_value(certs2, i);

    if (X509_cmp(a, b) != 0) {
      fprintf(stderr, "Certificate %u differs.\n", (unsigned) i);
      return 0;
    }
  }

  CBB_init(&cbb, der_len);
  if (!PKCS7_bundle_certificates(&cbb, certs2) ||
      !CBB_finish(&cbb, &result2_data, &result2_len)) {
    fprintf(stderr,
            "PKCS7_bundle_certificates failed the second time.\n");
    return 0;
  }

  if (result_len != result2_len ||
      memcmp(result_data, result2_data, result_len) != 0) {
    fprintf(stderr, "Serialisation is not stable.\n");
    return 0;
  }

  OPENSSL_free(result_data);
  OPENSSL_free(result2_data);
  sk_X509_pop_free(certs, X509_free);
  sk_X509_pop_free(certs2, X509_free);

  return 1;
}