Skip to content

Commit

Permalink
Upload artifacts, public object access
Browse files Browse the repository at this point in the history
  • Loading branch information
andrew committed Jan 21, 2024
1 parent 27be490 commit bb9078b
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 20 deletions.
5 changes: 0 additions & 5 deletions .github/workflows/rotate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,3 @@ jobs:
cargo run --manifest-path software/certifier/Cargo.toml --bin certifier-rotate
env:
CERTIPASTA_ROTATE_CONFIG: ${{ vars.CERTIPASTA_ROTATE_CONFIG }}
- uses: actions/upload-artifact@v4
with:
name: certipasta-root-certs
path: spaghettinuum_s.crt
if-no-files-found: error
6 changes: 6 additions & 0 deletions infra/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ fn main() {
members: vec![format!("serviceAccount:{}", pipeline_service_account.email()).into()].into(),
role: "roles/storage.objectUser".into(),
}.build(stack);
BuildStorageBucketIamBinding {
tf_id: "zNAAQLQ2V".into(),
bucket: certs_bucket.name().into(),
members: vec!["allUsers".into()].into(),
role: "roles/storage.objectViewer".into(),
}.build(stack);
let enable_gcp_keys_api = BuildProjectService {
tf_id: "zBXWMHWWS".into(),
service: "cloudkms.googleapis.com".into(),
Expand Down
6 changes: 2 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ In order to view websites certified by certipasta you'll need to install the roo

The certificates are restricted to the `.s` top level domain.

You can find the latest set of certificates in the build artifacts. The certs last for roughly two years, and are rotated once a year by the repository pipeline.

In most browsers if you download the certificate you'll be prompted to install it, although if package managers package such that it gets installed using normal procedures updated along with operating system updates that would be ideal.
You can find the latest active cert bundle at <https://storage.googleapis.com/zlr7wmbe6/spaghettinuum_s.crt>. The certificates last for roughly two years, and are rotated once a year by the repository pipeline - there's one year before the new certificate becomes active and the previous is no longer used to issue certificates.

# Issuing leaf certificates for your site

Expand Down Expand Up @@ -52,4 +50,4 @@ There are two ways to intercept traffic:

All Spaghettinuum DNS lookups are signed by the identity, so there's no way to forge a record without compromising the identity itself. An attacker could repeat a previously published record with an address the owner no longer controls, but as long as a newer record exists the network should reject this.

Intercepting IP traffic is not specific to this usage and out of scope.
Methods for intercepting IP traffic is not specific to this service.
31 changes: 20 additions & 11 deletions software/certifier/src/bin/certifier-rotate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@ use loga::{
};
use mime::Mime;
use tokio::{
fs::{
write,
},
time::sleep,
};
use x509_cert::{
Expand Down Expand Up @@ -101,6 +98,7 @@ struct Args {

const TAG_ISSUE_START: &'static str = "start";
const TAG_ISSUE_END: &'static str = "end";
const BUCKET_PREFIX_VERSION: &'static str = "generations";

fn get_ver_short_id(full_id: &str) -> Result<String, loga::Error> {
return Ok(
Expand Down Expand Up @@ -213,7 +211,7 @@ async fn generate_version(
storage_client
.objects()
.insert(Object {
name: Some(ver_short_id.clone()),
name: Some(format!("{}/{}", BUCKET_PREFIX_VERSION, ver_short_id)),
..Default::default()
}, &bucket_gcpid)
.upload_resumable(Cursor::new(cert_pem.as_bytes()), Mime::from_str("application/x-pem-file").unwrap())
Expand Down Expand Up @@ -304,10 +302,13 @@ async fn main() {
break;
};
for v in new_objects {
let Some(id) = v.name else {
let Some(object_key) = v.name else {
log.log(WARN, "Received obj missing name/id! Skipping...");
continue;
};
let Some(version_short_id) = object_key.strip_prefix(&format!("{}/", BUCKET_PREFIX_VERSION)) else {
continue;
};
let metadata = v.metadata.unwrap_or_default();
let create_time =
v.time_created.stack_context(log, "Missing created time for object from gcp api")?;
Expand Down Expand Up @@ -348,11 +349,11 @@ async fn main() {
log.log_with(
INFO,
"Surveying, found cert",
ea!(id = id, issue_start = issue_start.dbg_str(), issue_end = issue_end.dbg_str()),
ea!(id = object_key, issue_start = issue_start.dbg_str(), issue_end = issue_end.dbg_str()),
);
view.objects.push(ViewObject(Rc::new(RefCell::new(ViewObject_ {
object_key: id.clone(),
version_short_id: id,
object_key: object_key.clone(),
version_short_id: version_short_id.to_string(),
create_time: create_time,
issue_start: issue_start,
issue_end: issue_end,
Expand Down Expand Up @@ -615,10 +616,18 @@ async fn main() {
}
certs.extend(body.as_bytes());
}
let artifact_path = "spaghettinuum_s.crt";
write(artifact_path, certs)
let artifact_name = "spaghettinuum_s.crt";
let url = format!("https://storage.googleapis.com/{}/{}", config.bucket, artifact_name);
storage_client
.objects()
.insert(Object {
name: Some(artifact_name.to_string()),
..Default::default()
}, &config.bucket)
.upload_resumable(Cursor::new(&certs), Mime::from_str("application/pem-certificate-chain").unwrap())
.await
.stack_context_with(log, "Error witing artifact PEM (as .crt)", ea!(path = artifact_path))?;
.stack_context_with(log, "Error uploading bundle", ea!(object = url))?;
eprintln!("Bundle was uploaded to {}", url);
return Ok(());
}

Expand Down

0 comments on commit bb9078b

Please sign in to comment.